Chat room source code development, scanning code login simple implementation

Keywords: Redis

preface

With the development of science and technology, people can log in to the chat room source code in a variety of ways. In addition to logging in with a third-party account, they can also scan the code to log in. The specific implementation code is as follows:

Realization idea


The user's choice to scan the code for login can be regarded as A: the front end of the chat room source code sends an authorization request and waits for the app to scan the code.
Scanning the code using the app can be regarded as B: scanning the code for authorization and returning a temporary Token for secondary authentication.
The user's login confirmation on the app can be regarded as C: perform login confirmation and authorize the user to log in on the Web.
The chat room source code back-end returns an official Token after the user confirms login, which can be regarded as step D.
The subsequent front end accesses the background interface according to the formal Token, and the formal operation on the Web end can be regarded as E and F.

Reasons for secondary certification

The reason why the user needs to confirm the login again after scanning the code, rather than directly log in to the chat room source code, is for the sake of user security, so as to avoid the user scanning the QR code that others need to log in and logging in directly without confirmation, which may lead others to access our information in the chat room source code without our knowledge.

Implementation steps

1. Users access the chat room source code and select scan code to log in

When the user selects the chat room source code scanning login, he will send a QR code generation request to the back end. The back end will generate UUID and save it to Redis (fixed effective time). The status is set to UNUSED. If the Redis cache expires, it will be expired. The chat room source code front end will generate QR code according to the content returned by the back end, And set a timer to send a request to the back end every other period of time according to the UUID in the content of the QR code to obtain the status of the QR code and update the content displayed on the interface.

Generate QR code backend interface:

/**
 * Generate QR code content
 *
 * @return result
 */
@GetMapping("/generate")
public BaseResult generate() {
    String code = IdUtil.simpleUUID();
    redisCache.setCacheObject(code, CodeUtils.getUnusedCodeInfo(), 
                              DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
    return BaseResult.success(GENERATE_SUCCESS, code);
}

The front end of the chat room source code obtains the content and generates a QR Code:

getToken() {
    this.codeStatus = 'EMPTY'
    this.tip = 'Obtaining login code, please wait'
    // Effective time 60 seconds
    this.effectiveSeconds = 60
    clearInterval(this.timer)
    request({
        method: 'get',
        url: '/code/generate'
    }).then((response) => {
        // If the request is successful, set the QR code content and update relevant information
        this.code = `${HOST}/code/scan?code=${response.data}`
        this.codeStatus = 'UNUSED'
        this.tip = 'Please use your mobile phone to scan the code to log in'
        this.timer = setInterval(this.getTokenInfo, 2000)
    }).catch(() => {
        this.getToken()
    })
}

The interface for the chat room source code back end to return QR code status information:

/**
 * Get QR code status information
 *
 * @param code QR code
 * @return result
 */
@GetMapping("/info")
public BaseResult info(String code) {
    CodeVO codeVO = redisCache.getCacheObject(code);
    if (codeVO == null) {
        return BaseResult.success(INVALID_CODE, StringUtils.EMPTY);
    }
    return BaseResult.success(GET_SUCCESS, codeVO);
}

Chat room source code front end polling to obtain QR code status:

getTokenInfo() {
    this.effectiveSeconds--
    // QR code expired
    if (this.effectiveSeconds <= 0) {
        this.codeStatus = 'EXPIRE'
        this.tip = 'QR code has expired, please refresh'
        return
    }
    // Polling and querying QR code status
    request({
        method: 'get',
        url: '/code/info',
        params: {
            code: this.code.substr(this.code.indexOf('=') + 1)
        }
    }).then(response => {
        const codeVO = response.data
        // QR code expired
        if (!codeVO || !codeVO.codeStatus) {
            this.codeStatus = 'EXPIRE'
            this.tip = 'QR code has expired, please refresh'
            return
        }
        // QR code status is logging in
        if (codeVO.codeStatus === 'CONFIRMING') {
            this.username = codeVO.username
            this.avatar = codeVO.avatar
            this.codeStatus = 'CONFIRMING'
            this.tip = 'Code scanning succeeded. Please confirm on your mobile phone'
            return
        }
        // QR code status is confirm login
        if (codeVO.codeStatus === 'CONFIRMED') {
            clearInterval(this.timer)
            const token = codeVO.token
            store.commit('setToken', token)
            this.$router.push('/home')
            Message.success('Login succeeded')
            return
        }
    })
}

2. Scan the QR code with the mobile phone, and the QR code status changes

When the user scans the code using the mobile phone (logged in and is the correct app, otherwise the code scanning will jump to the publicity page customized by the chat room source code), the status of the QR code will be updated to the status of CONFIRMING (to be confirmed), and the user name and Avatar information will be saved in the Redis cache for front-end use and display. In addition, the user's login information will be returned (login address, browser, operating system) is displayed to the app, and a temporary Token is generated to the app (fixed effective time).

Background processing of chat room source code when scanning code:

/**
 * Process QR codes in unused status
 *
 * @param code QR code
 * @param token token
 * @return result
 */
private BaseResult handleUnusedQr(String code, String token) {
    // Verify the token passed by app side access
    boolean isLegal = JwtUtils.verify(token);
    if (!isLegal) {
        return BaseResult.error(AUTHENTICATION_FAILED);
    }
    // Save user name and avatar information for front-end display
    String username = JwtUtils.getUsername(token);
    CodeVO codeVO = CodeUtils.getConfirmingCodeInfo(username, DEFAULT_AVATAR_URL);
    redisCache.setCacheObject(code, codeVO, DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
    // Return the login address, browser, operating system and a temporary token to the app
    String address = HttpUtils.getRealAddressByIp();
    String browser = HttpUtils.getBrowserName();
    String os = HttpUtils.getOsName();
    String tmpToken = JwtUtils.sign(username);
    // The temporary token is used as the key, the user name is, and the content is stored in redis
    redisCache.setCacheObject(tmpToken, username, DEFAULT_TEMP_TOKEN_EXPIRE_MINUTES, TimeUnit.MINUTES);
    LoginInfoVO loginInfoVO = new LoginInfoVO(address, browser, os, tmpToken);
    return BaseResult.success(SCAN_SUCCESS, loginInfoVO);
}

3. Confirm login by mobile phone

When the user clicks confirm login in the app, it will send a request for updating the status with the generated temporary Token, and the status of the QR code will be updated to the CONFIRMED status. At the same time, the back-end of the chat room source code will generate a formal Token and save it in Redis. The front-end will obtain the Token when polling the update status, and then use the Token to log in.

Back end processing confirmation login code:

/**
 * Process QR codes in unconfirmed status
 *
 * @param code QR code
 * @param token token
 * @return result
 */
private BaseResult handleConfirmingQr(String code, String token) {
    // Use the temporary token to obtain the user name and delete the temporary token from redis
    String username = redisCache.getCacheObject(token);
    if (StringUtils.isBlank(username)) {
        return BaseResult.error(AUTHENTICATION_FAILED);
    }
    redisCache.deleteObject(token);
    // A formal token is generated according to the user name and saved in redis for use by the front end
    String formalToken = JwtUtils.sign(username);
    CodeVO codeVO = CodeUtils.getConfirmedCodeInfo(username, DEFAULT_AVATAR_URL, formalToken);
    redisCache.setCacheObject(code, codeVO, DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
    return BaseResult.success(CONFIRM_SUCCESS);
}

The above is the whole content of "chat room source code development and simple implementation of code scanning login". I hope it will be helpful to you.

Posted by greekuser on Fri, 15 Oct 2021 02:21:53 -0700