Member’s Login Session Token Help – Better Wix Coding From Lessons Learned

This is a simple solution with a longer explanation …
I thought I should post this to help those whom are using login session tokens on their sites (for their member’s area [aka site’s customers] logins). Most coders are familiar with uncovering nuances and revelations after multiple tries and/or reads on docs. That isn’t an always case, but it does happen.

I recently encountered a situation that is mentioned in Wix docs but not apparent in whole; which is regarding session tokens to login a user. Basically, for a session token type login, there is frontend code that completes the login and there is backend code that initially gets/generates a session token. This type of usage is needed for remote and/or 3rd party type logins.

The nuance I discovered is that in the second step, which is to complete the login from the frontend, you need to utilize a frontend function (‘ onLogin() ’) from the ‘wix-users’ library. This is because the ‘wix-users’ library should be used once the page is loaded, which can be utilized through the ‘ onReady() ’ event-handler like ‘ $w.onReady() ’. This is clearly announced in the Wix docs, while the part that a login success (completion) technically is its own promise, and thereby needs to be called is not so apparent. The login from the frontend Wix is a void type promise. Moreover that, those who are familiar with browser usage would know that there is information being exchanged in order to have a completed login that will maintain a session’s persistence throughout the member’s usage. Therefore, we need to utilize the ‘ onLogin() ’ in order to provide seamless usage for a member we are logging in. This is helpful if we are handling code that needs the user logged-in and/or want to move to other pages that are member-area restricted.

As mentioned, this is easy to handle, as you can see in the code below. I have provided the two optional ways to do this – via Email & Password -OR- Email only .

-------------------- THIS IS BACKEND CODE (start) --------------------
// Published 2019-09-23
/// Make sure to check for new updates in Wix docs
/// API-Reference: https://www.wix.com/corvid/reference 
/// Help-Center: https://support.wix.com/en/article/corvid-security-considerations (search from top-right bar)

/// Place this file in "backend", and name this file: 'login.jsw' -- otherwise use any unique name, but remember to change it in the front-end (page's) code.
/// Using ".jsw" identifies this as a Web-Module (node_modules), which allows to bring in other (outside) code repositories and services - e.g. Twilio, etc.

import wixUsers from 'wix-users-backend';

/*********************************
 * backend-side login code *
 *********************************/

/// Option-1 with both Email & Password.
/// This Exported Function will GET a session token from both an email & password input. 
export function getLoginToken(email, password) {
 return wixUsers.login(email, password)
        .then((sessionToken) => {
 return { "sessionToken": sessionToken, "approved": true };
        });
} // End of Exported-Function 'getLoginToken'

/// Option-2 with Email Only.
/// This Exported Function will GENERATE a session token with only the email input. 
/// This is not my preferred way, but may be the only (wix avail) option for things like 3rd party auths.
export function generateLoginToken(email) {
 return wixUsers.generateSessionToken(email)
        .then((sessionToken) => {
 return { "sessionToken": sessionToken, "approved": true };
        });
} // End of Exported-Function 'generateLoginToken'
-------------------- THIS IS BACKEND CODE (end) --------------------

-------------------- THIS IS FRONTEND CODE (start) --------------------

// Published 2019-09-23
/// Make sure to check for new updates in Wix docs
/// API-Reference: https://www.wix.com/corvid/reference 
/// Help-Center: https://support.wix.com/en/article/corvid-security-considerations (search from top-right bar)

import wixWindow from 'wix-window';
import wixUsers from 'wix-users';
import wixLocation from 'wix-location';
import { generateLoginToken, getLoginToken } from 'backend/login.jsw';

/*********************************
 * client-side login code *
 *********************************/

/// It is better to place this one Wix function 'wixUsers.onLogin()' on the "Site" tab instead of the "Page", which executes this code regardless of the page that is in play - make sure though, that is your intent, since this a log-in flow.
 /// This Gets Called upon the page's Log-in (when) being ready.
 /// This is IMPORTANT if you are using Member Area restricted pages and want to move to that page upon a login.
 wixUsers.onLogin( (user) => {
 let userId = user.id;           // EX) "r5cme-6fem-485j-djre-4844c49"
 let isLoggedIn = user.loggedIn; // should be 'true' here.
 let userRole = user.role;       // EX) "Member"
 console.log(`From ON-LOGIN. Here is User's Info: ID=='${userId}' && ROLE=='${userRole}'`);
 console.log(`From ON-LOGIN, Is User Logged-In? '${isLoggedIn}'`);
 wixLocation.to("/myWelcomePage");  //Change the URL ending to whatever page you want to send the user to after they log in.
 console.log("From ON-LOGIN - Moving to New Page That is Member Restricted");
}); // End of Wix's Log-In Ready Function.

/// Place this on the login page (not the site but the page itself)  

/// This Gets Called upon the page loading to be ready
$w.onReady(function() {

/// Option-1 with both Email & Password.
/// Showing 2 button examples although in reality should have 1 button for 1 login.
/// This is tied to the button added in Wix-Web's UI, with the tag renamed to 'button01' -- Name it whatever (uniquely) you'd like.
/// Personally I don't prefer this flow, due to security reasons, although based on your needs
/// it maybe the only (Wix) available solution - e.g. 3rd party Auth.
 $w("#button01").onClick((event) => {
 // Get current values
 let useEmail = String($w("#email").value);
 let usePassword = String($w("#password").value);
 // call backend function
 getLoginToken(useEmail, usePassword)
    .then((loginResult) => {
 // if approved log the user in with the session token
 if (loginResult.approved) {
 wixUsers.applySessionToken(loginResult.sessionToken);
 console.log("Get-Token-User-Is-APPROVED.");
 let isLoggedIn = wixUsers.currentUser.loggedIn // will be 'false' here.
 console.log(`From Get-Token, Is User Logged-In? '${isLoggedIn}'`);
        }
 // if not approved log a message
 else {
 console.log("Get-Token-User-NOT-Approved.");
        }
    });
    }) // End of "button01" Click Action

 /// Option-2 with Email Only.
 /// Showing 2 button examples although in reality should have 1 button for 1 login.
 /// This is tied to the button added in Wix-Web's UI, with the tag renamed to 'button02' -- Name it whatever (uniquely) you'd like.
 $w("#button02").onClick((event) => {
 // Get current value
 let useEmail = String($w("#email").value);
 // call backend function
 generateLoginToken(useEmail)
            .then((loginResult) => {
 // if approved log the user in with the session token
 if (loginResult.approved) {
 wixUsers.applySessionToken(loginResult.sessionToken);
 console.log("Generate-Token-User-Is-APPROVED.");
 let isLoggedIn = wixUsers.currentUser.loggedIn // will be 'false' here.
 console.log(`From Generate-Token, Is User Logged-In? '${isLoggedIn}'`);
                }
 // if not approved log a message
 else {
 console.log("Generate-Token-User-NOT-Approved.");
                }
            });
    }) // End of "button02" Click Action
 
}) // End of Wix's Page Ready Function
-------------------- THIS IS FRONTEND CODE (end) --------------------

I hope this is helpful to someone …


For using a remote login, see my other post. This post explains how to make it work but does not provide all the code to complete it - explained why there.

7 Likes

Hey, nice tutorial. I wanted to create a mobile app in React Native that uses my Wix site data (Members, Purchase Plans, Media, …) However, I noticed that it is quite complicated.
The backend APIs does not expose all information that I need. I managed to get the data from my Collections, but I need to use methods such as ‘getCurrentMemberOrders’ from ‘wix-paid-plans’; and this is not available in the backend side.
Today everything is moving towards omni-channel. But if I can’t create APIs that for my mobile app that consume the same content as my web/wix app; I’m afraid I might need to move away from Wix