Wechat scan code authorized login process:

  1. Users scan the qr code on a page that displays it for authorization
  2. The page displays the specified URL with the parameter code
  3. The front-end requests tokens for permission authentication from the server through code
  4. Subsequent front-end requests put tokens in the request header as identification

Problems that need to be solved

According to the above process, the simplest way for the front end is to get the code from the URL for subsequent operations after scanning the code and jumping back to the system.

However, because of the actual situation of the company, the whole process of scanning code login is not so simple.

Only fixed domain names can be displayed after code scanning

First of all, the domain name of wechat scanning code is fixed, but the domain name of general company projects in different development (or production) environment is not the same, so that users can not jump to the correct system address after scanning code.

The idea to solve this problem is to build a transfer platform. After scanning the code and jumping to the transfer platform, the transfer platform will add code parameters to the corresponding development (or production) environment address of the system, and then jump. The system can carry out subsequent operations after getting the code in the URL.

Embedded QR code

Second, the company leaders required that the QR code used for login be embedded in the system’s own login page, rather than opening a separate page to display the QR code.

It is also very simple to solve this problem. We can embed the TWO-DIMENSIONAL code page into the login page of the system through iframe. After scanning the code, the user will jump to the transfer platform within the IFrame. Pushes the code to the system outside the IFrame. After receiving the code, the system performs subsequent operations.

Too lazy to transfer the platform into a service

But here’s the problem again. Active push means that the server can actively push information to the client without waiting for the client to respond to the request. In the above login process, the transfer platform acts as a server and actively pushes code to the system. However, our company has no experience in deploying Node project, and it takes energy to maintain the transfer platform after deployment.

So what is an easy way to communicate between the relay platform and the system? LocalStorage (or SessionStorage) can do this. We can store code in the browser cache through LocalStorage on the transfer platform. After jumping back to the system, the system will obtain the code from the browser cache.

However, the disadvantage of LocalStorage is that it cannot communicate across domains. Caches between different domains cannot be shared. However, the good news is that all projects in our company are deployed under the same domain name in a certain development (or production) environment, but different projects have different paths, so that the transfer platform and system under the same domain name can share the cache. At the same time, the transit platform can be a static page without having to be a Node service.

Complete login process

To sum up, the whole specific login process is like this:

  1. The QR code page is embedded in the login page of the system through iframe
  2. After scanning codes, the user redirects to the transfer platform in the production environment in the IFrame. The redirect address contains domain name parameters and code parameters of the development (or production) environment where the current system resides.
  3. The transfer platform in the production environment obtains domain name parameters from the URL and carries the code parameter to the transfer platform with the corresponding domain name.
  4. The transfer platform of the corresponding domain name caches the code with LocalStorage and redirects it to the system of the corresponding domain name.
  5. The system retrieves the code from the cache and uses the code to request the token for subsequent permission authentication back end.

Code implementation

Erp system:

const BeforeScan: FC = () = > {
  useEffect(() = > {
    const nextUrl = `The ${window.location.protocol}//The ${window.location.host}/passport`
    const redirect_url = encodeURIComponent(
      `https://amazing.com/passport?redirect=${nextUrl}`.)// @ts-ignore
    const wwLogin = new WxLogin({
      self_redirect: true.id: 'login_container'.appid: appid,
      scope: 'snsapi_login'.redirect_uri: redirect_url,
      state: UUID.generate(),
      style: ' '.href: ' ',}}), [])return <div id='login_container' />
}

const Login: FC = () = > {
  const timer = useRef<NodeJS.timer | null> (null)
  
  const getCode = () = > {
    const msg = JSON.parse(
      sessionStorage.getItem('passport__wechat_login_code') | |'{}'.)returnmsg? .code }const resetMsg = () = > {
    sessionStorage.removeItem('passport__wechat_login_code')
    clearInterval(timerRef.current as NodeJS.Timer)
    timerRef.current = null
  }
  
  const loginLogic = () = > {
    const code = getCode()
    if (code) {
      resetMsg()
      getToken(code)
    }
  }
  
  useEffect(() = > {
    timerRef.current = setInterval(loginLogic, 1000)
    return () = > {
      resetMsg()
    }
  }, [])
  
  return (
    <div>
      <BeforeScan />
    </div>)}Copy the code

Transfer platform Passport:

var urlParams = new URLSearchParams(window.location.search)
var code = urlParams.get('code')
var redirect = urlParams.get('redirect')

// Call window.location.replace asynchronously to prevent some asynchronous operations from being incomplete
function replaceUrl(url) {
  setTimeout(function () {
    window.location.replace(url)
  }, 500)}function handleLogin() {
  var timestamp = (Date.now() / 1000) | 0
  var obj = { code: code, timestamp: timestamp }
  window.sessionStorage.setItem(
    'passport__wechat_login_code'.JSON.stringify(obj),
  )
  replaceUrl('/erp')}// Get the redirect URL from query and redirect to the corresponding domain name (used to log into the ERP of the test environment through amzaing.com).
// Keep all current queries when jumping, but remove the redirect.
function handleRedirect() {
  if (redirect) {
    var redirectUrl = new URL(redirect)
    urlParams.forEach(function (value, key) {
      if(key ! ='redirect') {
        redirectUrl.searchParams.set(key, value)
      }
    })
    replaceUrl(redirectUrl.toString())
    return true
  }
  return false
}

function main() {
  var redirected = handleRedirect()
  if(! redirected) { handleLogin() } } main()Copy the code

Deficiency in

There are some disadvantages of the scan code login method above:

  • The front-end in the local environment is not able to scan login. In this way, the system and the transfer platform need to be in the same domain. For the local environment, a port has been occupied by the system, so the transfer platform cannot use this port.
  • The login wait time is too long. Procedure

Therefore, the best way to scan code login is to build the transfer platform into a real system service, so that the transfer platform can actively push data to the system. Moreover, after building the transfer platform into a system service, the login logic of all systems can be integrated into the transfer platform, thus building a unified login platform, so that other systems do not need to pay attention to the login logic.