微信扫码登录

获取临时域名,配置公众号信息等参考: 

微信公众号网页授权登录_m0_53611007的博客-CSDN博客

开启测试号网页授权功能并配置这一项可以不配置

不过扫码登录要配置的是:

 如果微信服务器请求这个url时 自己在这里设置的token与接口不对应时无法配置成功的

这个接口代码如下:

@RequestMapping ("/checkSign")
    public String checkSign ( HttpServletRequest request) throws Exception {
        //获取微信请求参数
        String signature = request.getParameter ("signature");
        String timestamp = request.getParameter ("timestamp");
        String nonce = request.getParameter ("nonce");
        String echostr = request.getParameter ("echostr");
        //参数排序。 token 就要换成自己实际写的 token
        String [] params = new String [] {timestamp,nonce,"123456"} ;
        Arrays.sort (params) ;
        //拼接
        String paramstr = params[0] + params[1] + params[2] ;
        //加密
        //获取 shal 算法封装类
        MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1") ;
        //进行加密
        byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes ("UTF-8"));
        //拿到加密结果
        //String mysignature = WebUtils.byte2HexStr(digestResult);
        String mysignature = FileDataConvert.bytes2HexString(digestResult);
        mysignature=mysignature.toLowerCase(Locale.ROOT);
        //是否正确
        boolean signsuccess = mysignature.equals(signature);
        //逻辑处理
        if (signsuccess && echostr!=null) {
            //peizhi  token
            return echostr  ;//不正确就直接返回失败提示.
        }else{
            JSONObject jsonObject = callback(request);
            return jsonObject.toJSONString();
        }
    }
 @RequestMapping("callback")
    public JSONObject callback(HttpServletRequest request) throws Exception{
        //request中有相应的信息,进行解析
        WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml
        String messageType=message.getMsgType();								//消息类型
        String messageEvent=message.getEvent();								    //消息事件
        // openid
        String fromUser=message.getFromUser();									//发送者帐号
        String touser=message.getToUser();										//开发者微信号
        String text=message.getContent();										//文本消息  文本内容
        // 生成二维码时穿过的特殊参数
        String eventKey=message.getEventKey();									//二维码参数

        String uuid="";															//从二维码参数中获取uuid通过该uuid可通过websocket前端传数据
        String userid="";

        //if判断,判断查询
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code","200");
        if(messageType.equals("event")){
            //先根据openid从数据库查询  => 从自己数据库中查取用户信息
            jsonObject = null;
            if(messageEvent.equals("SCAN")){
                //扫描二维码
                //return "欢迎回来";
            }
            if(messageEvent.equals("subscribe")){
                //关注
                //return "谢谢您的关注";
            }
            //没有该用户
            if(jsonObject==null){
                //从微信上中拉取用户信息
                String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +getAccessToken() +
                        "&openid=" + fromUser +
                        "&lang=zh_CN";
                String result = HttpClientUtil.doGet(url);
                jsonObject = JSONObject.parseObject(result);
            }
            loginMap.put(eventKey,new CodeLoginKey(eventKey,fromUser));
            return jsonObject;
            //return userInfo.toString();
        }
        return jsonObject;
        //log.info("消息类型:{},消息事件:{},发送者账号:{},接收者微信:{},文本消息:{},二维码参数:{}",messageType,messageEvent,fromUser,touser,text,eventKey);
    }

点击登录js

function codeAuthLogin() {
        $.get("qcCodeLogin/getQrCode",
        function(data,status){
           console.log(data);
           sceneStr = data.sceneStr;
           $('#qrCodeId').attr('src',"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+data.ticket);
           $('#qrCodeId').show();
            t = window.setInterval(getOpenId,3000);
        });
    }

登录接口:

  // 微信开放平台二维码连接
    private final static String getQrCode= "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
    private final static String getToken= "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";

    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private HttpSession httpSession;
    // 模拟数据库存储或者缓存存储
    Map<String,CodeLoginKey> loginMap = new HashMap<>();

@GetMapping("/getQrCode")
    private JSONObject getQrCode(){
        try {
            // 获取token开发者
            String accessToken =getAccessToken();
            String getQrCodeUrl = getQrCode.replace("TOKEN", accessToken);
            // 这里生成一个带参数的二维码,参数是scene_str
            String sceneStr = getRandomString(8);
            String json="{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""+sceneStr+"\"}}}";
            String result  = HttpClientUtil.doPostJson(getQrCodeUrl,json);
            JSONObject jsonObject = JSONObject.parseObject(result);
            jsonObject.put("sceneStr",sceneStr);
            return jsonObject;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

这时我们可以获取微信给的二维码扫描二维码请求接口js

function getOpenId() {
        $.get("qcCodeLogin/getOpenId",{
            "eventKey":sceneStr
        },function (data) {
            if(data.code == 200){
                console.log("==================");
                console.log(data.data);
                window.clearInterval(t);
                alert("登录成功:"+data.data.openId);
            }
        });
    }

接口:

 @RequestMapping("getOpenId")
    public ResultJson getOpenId(String eventKey){
        if(loginMap.get(eventKey) == null){
            return ResultJson.failure(ResultCode.SERVER_ERROR,"未扫码成功!") ;
        }
        CodeLoginKey codeLoginKey = loginMap.get(eventKey);
        loginMap.remove(eventKey);
        return ResultJson.ok(codeLoginKey);
    }

整体代码:

@RestController
@RequestMapping("qcCodeLogin")
public class QrCodeLoginController {
    // 微信开放平台二维码连接
    private final static String getQrCode= "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
    private final static String getToken= "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";

    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private HttpSession httpSession;
    // 模拟数据库存储或者缓存存储
    Map<String,CodeLoginKey> loginMap = new HashMap<>();

    @GetMapping("/getQrCode")
    private JSONObject getQrCode(){
        try {
            // 获取token开发者
            String accessToken =getAccessToken();
            String getQrCodeUrl = getQrCode.replace("TOKEN", accessToken);
            // 这里生成一个带参数的二维码,参数是scene_str
            String sceneStr = getRandomString(8);
            String json="{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""+sceneStr+"\"}}}";
            String result  = HttpClientUtil.doPostJson(getQrCodeUrl,json);
            JSONObject jsonObject = JSONObject.parseObject(result);
            jsonObject.put("sceneStr",sceneStr);
            return jsonObject;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //length用户要求产生字符串的长度
    public static String getRandomString(int length){
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<length;i++){
            int number=random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    public String getAccessToken(){
        String accessToken = null;
        if(httpSession.getAttribute("code_access_token") != null){
            return httpSession.getAttribute("code_access_token").toString();
        }
        String getTokenUrl = getToken.replace("APPID", wxConfig.getAppId()).replace("SECRET", wxConfig.getAppSecret());
        String result = HttpClientUtil.doGet(getTokenUrl);
        JSONObject jsonObject = JSONObject.parseObject(result);
        accessToken = jsonObject.getString("access_token");
        httpSession.setAttribute("code_access_token",accessToken);
        return accessToken ;
    }


    @RequestMapping ("/checkSign")
    public String checkSign ( HttpServletRequest request) throws Exception {
        //获取微信请求参数
        String signature = request.getParameter ("signature");
        String timestamp = request.getParameter ("timestamp");
        String nonce = request.getParameter ("nonce");
        String echostr = request.getParameter ("echostr");
        //参数排序。 token 就要换成自己实际写的 token
        String [] params = new String [] {timestamp,nonce,"123456"} ;
        Arrays.sort (params) ;
        //拼接
        String paramstr = params[0] + params[1] + params[2] ;
        //加密
        //获取 shal 算法封装类
        MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1") ;
        //进行加密
        byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes ("UTF-8"));
        //拿到加密结果
        //String mysignature = WebUtils.byte2HexStr(digestResult);
        String mysignature = FileDataConvert.bytes2HexString(digestResult);
        mysignature=mysignature.toLowerCase(Locale.ROOT);
        //是否正确
        boolean signsuccess = mysignature.equals(signature);
        //逻辑处理
        if (signsuccess && echostr!=null) {
            //peizhi  token
            return echostr  ;//不正确就直接返回失败提示.
        }else{
            JSONObject jsonObject = callback(request);
            return jsonObject.toJSONString();
        }
    }
    @RequestMapping("callback")
    public JSONObject callback(HttpServletRequest request) throws Exception{
        //request中有相应的信息,进行解析
        WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml
        String messageType=message.getMsgType();								//消息类型
        String messageEvent=message.getEvent();								    //消息事件
        // openid
        String fromUser=message.getFromUser();									//发送者帐号
        String touser=message.getToUser();										//开发者微信号
        String text=message.getContent();										//文本消息  文本内容
        // 生成二维码时穿过的特殊参数
        String eventKey=message.getEventKey();									//二维码参数

        String uuid="";															//从二维码参数中获取uuid通过该uuid可通过websocket前端传数据
        String userid="";

        //if判断,判断查询
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code","200");
        if(messageType.equals("event")){
            //先根据openid从数据库查询  => 从自己数据库中查取用户信息
            jsonObject = null;
            if(messageEvent.equals("SCAN")){
                //扫描二维码
                //return "欢迎回来";
            }
            if(messageEvent.equals("subscribe")){
                //关注
                //return "谢谢您的关注";
            }
            //没有该用户
            if(jsonObject==null){
                //从微信上中拉取用户信息
                String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +getAccessToken() +
                        "&openid=" + fromUser +
                        "&lang=zh_CN";
                String result = HttpClientUtil.doGet(url);
                jsonObject = JSONObject.parseObject(result);
            }
            loginMap.put(eventKey,new CodeLoginKey(eventKey,fromUser));
            return jsonObject;
            //return userInfo.toString();
        }
        return jsonObject;
        //log.info("消息类型:{},消息事件:{},发送者账号:{},接收者微信:{},文本消息:{},二维码参数:{}",messageType,messageEvent,fromUser,touser,text,eventKey);
    }

    @RequestMapping("getOpenId")
    public ResultJson getOpenId(String eventKey){
        if(loginMap.get(eventKey) == null){
            return ResultJson.failure(ResultCode.SERVER_ERROR,"未扫码成功!") ;
        }
        CodeLoginKey codeLoginKey = loginMap.get(eventKey);
        loginMap.remove(eventKey);
        return ResultJson.ok(codeLoginKey);
    }
}

登录成功后返回用户信息的一个工具类:

public class CodeLoginKey {

    private String eventKey;
    private String openId;


    public CodeLoginKey(String eventKey, String openId) {
        this.eventKey = eventKey;
        this.openId = openId;
    }

    public String getEventKey() {
        return eventKey;
    }

    public void setEventKey(String eventKey) {
        this.eventKey = eventKey;
    }

    public String getOpenId() {
        return openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    @Override
    public String toString() {
        return "CodeLoginKey{" +
                "eventKey='" + eventKey + '\'' +
                ", openId='" + openId + '\'' +
                '}';
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值