谷粒学院微信扫码登录过程记录以及bug解决

做的是谷粒学院的微信登录,这里他提供的微信开放平台的信息好像出了问题,没有办法正常操作,这里做出如下改变:
原来的配置文件信息:

wx.open.app_id=wxed9954c01bb89b47
wx.open.app_secret=a7482517235173ddb4083788de60b90e
wx.open.redirect_url=http://guli.shop/api/ucenter/wx/callback

现在修改为:

wx.open.app_id=wxed9954c01bb89b47
wx.open.app_secret=a7482517235173ddb4083788de60b90e
wx.open.redirect_url=http://localhost:8160/api/ucenter/wx/callback

还要修改项目启动端口为8160。

ConstantWxUtil取到配置文件的信息:

@Component
public class ConstantWxUtil  implements InitializingBean {

    @Value("${wx.open.app_id}")
    private String appId;

    @Value("${wx.open.app_secret}")
    private String appSecret;

    @Value("${wx.open.redirect_url}")
    private String redirectUrl;

    public static String WX_OPEN_APP_ID;
    public static String WX_OPEN_APP_SECRET;
    public static String WX_OPEN_REDIRECT_URL;

    @Override
    public void afterPropertiesSet() throws Exception {
        WX_OPEN_APP_ID = appId;
        WX_OPEN_APP_SECRET = appSecret;
        WX_OPEN_REDIRECT_URL = redirectUrl;
    }
}

生成二维码方法:

 @GetMapping("login")
    public String genQrConnect(HttpSession session) {

        // 微信开放平台授权baseUrl
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";

        // 回调地址
        String redirectUrl = ConstantWxUtil.WX_OPEN_REDIRECT_URL;
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8"); //url编码
        } catch (UnsupportedEncodingException e) {
            throw new GuliException(20001, e.getMessage());
        }
        String state = "imhelen";
        System.out.println("state = " + state);


        //生成qrcodeUrl
        String qrcodeUrl = String.format(
                baseUrl,
                ConstantWxUtil.WX_OPEN_APP_ID,
                redirectUrl,
                state);

        return "redirect:" + qrcodeUrl;
    }

扫码登录方法:

@Autowired
    private UcenterMemberService memberService;

    @GetMapping("callback")
    public String callback(String code, String state, HttpSession session) {
        //获取到code
        //拿着code请求微信固定地址,得到access_token和openid
        //得到授权临时票据code
        System.out.println("code = " + code);
        System.out.println("state = " + state);

        try{
            String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                    "?appid=%s" +
                    "&secret=%s" +
                    "&code=%s" +
                    "&grant_type=authorization_code";

            String accessTokenUrl = String.format(baseAccessTokenUrl,
                    ConstantWxUtil.WX_OPEN_APP_ID,
                    ConstantWxUtil.WX_OPEN_APP_SECRET,
                    code);

            String accessTokenInfo = HttpClientUtils.get(accessTokenUrl);
            //获取accessToken和openid

            String result = null;

            Gson gson=new Gson();
            HashMap mapAccessToken = gson.fromJson(accessTokenInfo, HashMap.class);
            String access_token = (String) mapAccessToken.get("access_token");
            String openid = (String) mapAccessToken.get("openid");



            //将扫码人信息添加到数据库
            //判断数据库中是否有重复微信信息
            UcenterMember member=memberService.getOpenIdMember(openid);
            if (member==null){

                String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                        "?access_token=%s" +
                        "&openid=%s";

                String userInfoUrl = String.format(
                        baseUserInfoUrl,
                        access_token,
                        openid
                );
                String userInfo = HttpClientUtils.get(userInfoUrl);
                HashMap userInfoMap = gson.fromJson(userInfo, HashMap.class);
                String nickname = (String) userInfoMap.get("nickname");
                String headimgurl = (String) userInfoMap.get("headimgurl");


                //添加
                member=new UcenterMember();
                member.setNickname(nickname);
                member.setAvatar(headimgurl);
                member.setOpenid(openid);
                memberService.save(member);

            }
            //使用jwt根据member对象生成token字符串
            String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());
            return "redirect:http://localhost:3000?token="+jwtToken;

        }catch (Exception e){
            throw new GuliException(20001,"登录失败");
        }

    }

前端页面方法:意义:当页面初始化的时候,判断路径中是否有token参数,如果有,调用wxLogin方法,把token放到cookie中,再调用获取用户信息方法,根据token获取用户信息展示。

 created() {

    //获取路径中的token的值
    this.token=this.$route.query.token
    if(this.token){
      this.wxLogin()
    }

  },

  methods: {
    //微信登录
    wxLogin(){
      cookie.set("guli_token",this.token,{domain: 'localhost'})
       cookie.set('guli_ucenter','', { domain: 'localhost' })
       loginApi.getLoginInfo()
        .then(response=>{
          this.loginInfo= response.data.data.userInfo
           cookie.set('guli_ucenter', this.loginInfo, { domain: 'localhost' })
        })
    }
    }

图解如下:
在这里插入图片描述

在这里插入图片描述
简单概括一下:首先拿着app_id,app_secret,redirect_url去请求微信的一个接口,微信会返回来一个二维码,用户扫码确认登录以后,执行callback回调方法,会传过来两个值,一个state,一个code,,然后拿着code请求微信提供的一个接口,得到两个值,一个access_token为访问凭证,一个openid为每个微信的唯一标识,拿着这两个值再去请求微信的一个接口,就可以得到扫码人的微信头像昵称等信息。

个人理解为,拿着微信应用的钥匙打开一道门,得到一张地图,扫描地图得到钥匙,通过钥匙打开一道门,又得到一个钥匙,再打开一道门,才得到有用的信息。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值