background

There is an interesting requirement in this iteration. The description is very simple: our platform sends links to other platforms, and other platforms can click links to log in to our platform without feeling. The point is, login is successful and you don’t feel anything.

1. How do I log in?

First of all, let’s think about the question, why can’t I jump directly?

To figure this out, we need to think about what our own framework does for us when we open a link. Anyone familiar with VUE knows the route front-guard, which, yes, triggers the router when entering the page. BeforeEach’s hook, you can think of it as a necessary step to a successful jump

So what does the frame do in this hook?

A. First, the page will check whether there is an account that has been logged in. The way to check whether there is an account is generally to check whether there is a local storage token. This token can be understood as an ID card obtained after logging in. With this ID card, you can travel freely in any interface without obstruction.

B. If the login page is displayed, the login page is displayed.

Knowing these, we know that in fact, as long as we can have a token, we can achieve our purpose. Ok, let’s think about how to get this token.

2. How to obtain a token?

In fact, the most direct way to obtain the token is to directly put the token in the link as a parameter in the background. The user clicks the link and the front-end directly obtains the parameter token of the browser and stores it locally. However, there is a drawback to this: the token has an expiration date and will still be redirected to the login page. So the best practice is to manually obtain the latest token for each jump.

How to obtain the latest token? Either call the login interface and pass in the user name and password to get the latest token, or directly pass an encrypted string generated by the user name and password to the background for parsing and then return the latest token. Both methods can achieve the purpose.

Ok, let’s go straight to the code. I started with something like this:

router.beforeEach((to, from, next) = > {
    // Whether there is automatic login can be determined by whether the jump link carries the token parameter
    if(!!!!! (to.query.token)){// Call the interface to get the token and store it locally
    }
    // Check whether tokens are stored locally
    if (localStorage.getItem('token')) {
        // Call the interface to get user information}}Copy the code

One problem with the above code is that it is not executed synchronously, because calling the interface to obtain the token is an asynchronous operation. It’s also easy to synchronize, so I won’t go over it here.

export const init=(callback) = >{
    // Call the interface to get the token
    // Call the interface to get user information
    callback()
}
Copy the code
import init from ".."
router.beforeEach((to, from, next) = > {
    // Check whether there is automatic login or whether tokens are stored locally
    if(!!!!! (to.query.token)||localStorage.getItem('token')) {
       init(callback) 
    }
}
Copy the code

3. The optimization

3.1 To this in fact, the basic function has been realized, but friends with obsessive-compulsive disorder and perfectionism will find that you jump over the link will be more parameters. It looks awkward and maybe risky. How do you get rid of it? Very simple

// Remove the token argument from the address bar
if (Reflect.has(to.query, 'token')) {
    Reflect.deleteProperty(to.query, 'token');
}
// Use replace because you don't want to return to the login page, because the login path is stored in the next route recordnext({ ... to,replace: true });
Copy the code

3.2 If I mean if, your page header will have a back button. For example, some details page headers will have a back button. At this time, because it is a direct jump, there is only one record of your current page in the routing record, so your back button click is invalid. You can look carefully at the browser’s back button. If the browser back button is disabled, you can’t go back. There are two ways around this too: either disable the back button as well, or decide to jump to a specific link if you can’t back up

if (window.history.length > 1) {
    this.$router.go(-1); // Return to the previous interface
} else {
    this.$router.push({
        path: 'xx'}); }Copy the code