Java微信扫码登录+websocket通知前端

1,vue前端登录页面

<script>
  export default {
    name: "login",
    data() {
      return {
        path: "ws://www.david10.com/studyassistant/websocket/",
        socket: "",
        date: Date.parse(new Date()),//时间戳
        mywin: '',//打开的窗口
      }
    },
    mounted() {
      this._jq();
      // this.webSocketFun();
      this.init();
      // this.wxChange()
    },
    methods: {
      roters() {
        this.$router.push({path: '/serviceText', query: {}});
      },

      init: function () {
        if (typeof (WebSocket) === "undefined") {
          alert("您的浏览器不支持socket")
        } else {
          // 实例化socket
          this.socket = new WebSocket(this.path + this.date)
          // 监听socket连接
          this.socket.onopen = this.open
          // 监听socket错误信息
          this.socket.onerror = this.error
          // 监听socket消息
          this.socket.onmessage = this.getMessage
        }
      },
      open: function () {
        console.log("socket连接成功")
        // this.wxChange();
      },
      error: function () {
        console.log("连接错误")
      },
      getMessage: function (msg) {
        // console.log('msg',msg)
        this.mywin.close();
        let data = JSON.parse(msg.data);
        if (data.code == 0) {
          this.$notify({
            title: '成功',
            message: '登录成功',
            type: 'success'
          });
          this.$store.commit('tokenAdd', data.msg);
          this.$store.commit('yesLogin');
          window.sessionStorage.setItem("isLogin", true);
          window.sessionStorage.setItem("token", data.msg);
          this.$router.push({path: '/index', query: {wx:data.msg}});
          //进来之后要改变默认token的值变成空,写在mian.js里面的赋值的东西不会默认改变的
          this.$http.defaults.headers.common['Authorization'] = data.msg;
        }
        if (data.code == 1) {
          this.$notify.error({
            title: '错误',
            message: data.msg
          });
          // console.log(data.msg)
        }

      },
      send: function () {
        this.socket.send(params)
      },
      close: function () {
        console.log("socket已经关闭")
      },

      //微信改变样式
      wxChange() {
        // let This = this;
        this.mywin = window.open("https://open.weixin.qq.com/connect/qrconnect?appid=&redirect_uri=&response_type=code&scope=snsapi_login&state=" + this.date + "#wechat_redirect", "", "width=500px,height=500px");

      //设置高度
      _jq() {
        $('.login').height($(window).height())
      },
    },
    destroyed() {
      // 销毁监听
      this.socket.onclose = this.close
    }
  }
</script>

2,websocket配置

(1)maven依赖:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
</dependency>
(2)ChatInterceptor.java
public class ChatInterceptor extends HttpSessionHandshakeInterceptor {
    /**
     *
     * @param request 请求
     * @param response 响应
     * @param wsHandler 处理器
     * @param attributes 请求的属性,会被传递到我们的handler中
     * @return  返回true代表放行 ,false代表拦截
     * @throws Exception
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
       //我们可以在这里向属性中添加一个值,这个值我们可以用作标记, map的key我们随意,只要能保证唯一性以及记住就行
        String s = request.getURI().toString();//获取请求地址,我们要求了 最后一个/后面是标记
        String name = s.substring(s.lastIndexOf("/" )+ 1);
        attributes.put("name", name);
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
(3)ChatMessageHandler.java
public class ChatMessageHandler extends TextWebSocketHandler {

    private static Map<String, WebSocketSession> allClient = new ConcurrentHashMap<>();

    public static Map<String, WebSocketSession> getAllClient() {
        return allClient;
    }

    /**
     *  当链接建立的时候执行, 相当于我们普通情况下 onOpen
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //保存到map中
        Map<String, Object> attributes = session.getAttributes();//拦截器中的那个map,里面放着我们的name
        allClient.put((String) attributes.get("name"), session);//保存了所有的链接
        super.afterConnectionEstablished(session);
    }

    /**
     * 处理文本消息 相当于我们的onMessage
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {


    }

    /**
     * 连接关闭 相当于 onClose
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
    }
}
(4)WebSocketConfig.java
@Configuration
@EnableWebSocket//开启websock
public class WebSockertConfig implements WebSocketConfigurer {

    /**
     * 注册websock 处理器,其实就是最终谁来处理请求
     * @param webSocketHandlerRegistry
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        //注册websock的地址为/websocket/* 并添加了一个拦截器, 拦截器中会将请求地址中的最后一部分放入到map中传递到我们的handler中,.我们要求了最后一部分就是标记
        webSocketHandlerRegistry.addHandler(new ChatMessageHandler(),"/websocket/*").addInterceptors(new ChatInterceptor()).setAllowedOrigins("*");
    }
}

3,微信登录回调后台接口

/**
     * V2.0.0微信扫码登录
     * @param code 微信回调的code
     * @param state 通信需要用到的标记
     */
    @RequestMapping("/callback")
    public void callback(String code,String state){
        Jedis jedis =null;
        logger.info("进入授权回调,code:{},state:{}",code,state);
        //1.通过code获取access_token
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        url = url.replace("APPID","你的id").replace("SECRET","你的secret").replace("CODE",code);
        String tokenInfoStr = HttpUtil.postData(url,"");
        logger.info("tokenInfoStr =========>"+tokenInfoStr);
        JSONObject tokenInfoObject = JSON.parseObject(tokenInfoStr);
        //2.通过access_token和openid获取用户信息
        String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
        userInfoUrl = userInfoUrl.replace("ACCESS_TOKEN",tokenInfoObject.getString("access_token")).replace("OPENID",tokenInfoObject.getString("openid"));
        String userInfoStr =  HttpUtil.postData(userInfoUrl,"");
        logger.info("userInfoObject:{}",userInfoStr);
        JSONObject jsStr = JSON.parseObject(userInfoStr);
        //3.获取信息

        String nickname = jsStr.getString("nickname");
        String headimgurl = jsStr.getString("headimgurl");
        String unionid = jsStr.getString("unionid");


        try {
                //你的登录逻辑代码
               
                //通过websocket通知登录成功并返回微信id
                WebSocketSession session = ChatMessageHandler.getAllClient().get(state);
                if  (session != null && session.isOpen()) {
                    ResultBean resultBean = ResultBean.setError(0, unionid);
                    String resultjson = JSON.toJSONString(resultBean);
                    session.sendMessage(new TextMessage(resultjson));
                }else {
                    ResultBean resultBean = ResultBean.setError(1, "请检查你的网络");
                    String resultjson = JSON.toJSONString(resultBean);
                    session.sendMessage(new TextMessage(resultjson));
                    logger.error("会话连接出错");
                }

        }catch (Exception e){
            e.printStackTrace();
            logger.error("微信登录失败");
        }

    }

你可能感兴趣的