基于springboot+websocket的扫码登陆(后端部分)

##原理:
前端生成二维码,存储随机ID,并注册到websocket的服务端,手机扫码后,带上token访问校验端,并且授权给核心工厂,确认登陆后,发送登录成功的信息和授权以后的token给前端,前端做token存储和页面跳转

附件:

文件名地址
后端压缩包scanLogin.zip
前端demo页面websocket.html

## 核心代码展示

1、websocket配置(启动器)

@SpringBootApplication
@EnableWebSocket
public class LoginDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(LoginDemoApplication.class, args);
    }
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

2、websocket服务端


import com.saoma.logindemo.factory.CodeFactory;
import org.springframework.stereotype.Component;

import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Classname WebSocketDemo
 * @Description
 * @Date 2021/2/209:52
 * @Author zjhchester
 */
@ServerEndpoint("/scanlogin/{code}")
@Component
public class WebSocketServer {
    private static Map<String, WebSocketServer> clients = new ConcurrentHashMap();
    private Session session;
    private String code;
    private static Integer threadStatus = 0;
    public WebSocketServer() {

    }
    private CodeFactory codeFactory = SpringUtil.getBean(CodeFactory.class);
    @OnOpen
    public void onOpen(@PathParam("code") String code, Session session) throws IOException {
        this.code = code;
        this.session = session;
        clients.put(code, this);

        System.out.println(code);
        codeFactory.setCode(code,session.toString());
        sendMessageTo("connect success!",code);
    }
    public void sendMessageTo(String message, String to) throws IOException {
        Iterator var3 = clients.values().iterator();
        while(var3.hasNext()) {
            WebSocketServer item = (WebSocketServer)var3.next();
            if (item.code.equals(to)) {
                item.session.getAsyncRemote().sendText(message);
            }
        }
    }
}

3、核心工厂

import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @Classname CodeFacotory
 * @Description 扫码登录核心工厂
 * @Date 2021/2/209:56
 * @Author zjhchester
 */
@Component
public  class CodeFactory {
    /**
     * key: 生成的随机码
     * value: 绑定的socket  sessionID
     */
    private static ConcurrentHashMap<String,String> codeFactory;
    static {
        codeFactory = new ConcurrentHashMap<>(1);
    }
    public String getCode(String code){
        return codeFactory.get(code);
    }
    public String setCode(String code,String session){
        return codeFactory.put(code,session);
    }
}

4、校验controller

import com.saoma.logindemo.conf.SpringUtil;
import com.saoma.logindemo.conf.WebSocketServer;
import com.saoma.logindemo.factory.CodeFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Objects;
import java.util.UUID;

/**
 * @Classname scanDemo
 * @Description
 * @Date 2021/2/209:50
 * @Author zjhchester
 */
@RestController
public class ScanDemoController {
    private final static String TRUE= "true";
    private final CodeFactory codeFactory;
    private final WebSocketServer webSocketServer;
    public ScanDemoController(CodeFactory codeFactory, WebSocketServer webSocketServer) {
        this.codeFactory = codeFactory;
        this.webSocketServer = webSocketServer;
    }

    /**
     * 校验登陆
     * @return result
     */
    @GetMapping("/codeverify")
    public String codeCreate(String code) throws IOException {
        String session = codeFactory.getCode(code);
        if(Objects.nonNull(session)){
            System.out.println(session);
            codeFactory.setCode(code,"true");
            webSocketServer.sendMessageTo("已在手机上扫描,请确认登录",code);
        }
        return code;
    }


    @GetMapping("/confirmlogin")
    public Boolean confirmLogin(String code) throws IOException {
        String verifyResult = codeFactory.getCode(code);
        if(TRUE.equals(verifyResult)){
            SpringUtil.getBean(WebSocketServer.class).sendMessageTo("登录成功",code);
            return true;
        }else{
            return false;
        }
    }
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值