广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Spring Boot实现微信扫码登录功能流程分析
  • 450
分享到

Spring Boot实现微信扫码登录功能流程分析

2024-04-02 19:04:59 450人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1. 授权流程说明第一步:请求CODE第二步:通过code获取access_token第三步:通过access_token调用接口2. 授权流程代码3. 用户登录和登出4. sp

微信开放平台:微信扫码登录功能

官方文档:https://developers.weixin.qq.com/doc/oplatfORM/WEBsite_App/WeChat_Login/Wechat_Login.html

1. 授权流程说明

微信OAuth3.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth3.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。

微信OAuth3.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:

① 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

② 通过code参数加上AppID和AppSecret等,通过api换取access_token;

③ 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

第一步:请求CODE

第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接:Https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

返回说明

用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数

redirect_uri?code=CODE&state=STATE

若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数

redirect_uri?state=STATE

例如:登录一号店网站应用 https://passport.yhd.com/wechat/login.do 打开后,一号店会生成state参数,跳转到 https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3D6be0a4035d839573b04816624a415e#wechat_redirect 微信用户使用微信扫描二维码并且确认登录后,PC端会跳转到 https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e

第二步:通过code获取access_token

通过code获取access_token

https://api.weixin.qq.com/sns/oauth3/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

返回说明

正确的返回:

{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"uNIOnid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

错误返回样例:

{"errcode":40029,"errmsg":"invalid code"}
  • Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
  • access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
  • refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。

第三步:通过access_token调用接口

获取access_token后,进行接口调用,有以下前提:

  1. access_token有效且未超时;
  2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。

对于接口作用域(scope),能调用的接口有以下:

2. 授权流程代码

因为微信开放平台的AppiD和APPSecret和微信公众平台的AppiD和AppSecret都是不同的,因此需要配置一下:

# 开放平台
wechat.open-app-id=wx6ad144e54af67d87
wechat.open-app-secret=91a2ff6d38a2bbccfb7e9f9079108e2e
@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WechatAccountConfig {

    //公众号appid
    private String mpAppId;
    //公众号appSecret
    private String mpAppSecret;
    //商户号
    private String mchId;
    //商户秘钥
    private String mchKey;
    //商户证书路径
    private String keyPath;
    //微信支付异步通知
    private String notifyUrl;
    //开放平台id
    private String openAppId;
    //开放平台秘钥
    private String openAppSecret;
}
@Configuration
public class WechatOpenConfig {
    @Autowired
    private WechatAccountConfig accountConfig;
    @Bean
    public WxMpService wxOpenService() {
        WxMpService wxOpenService = new WxMpServiceImpl();
        wxOpenService.setWxMpConfigStorage(wxOpenConfigStorage());
        return wxOpenService;
    }
    public WxMpConfigStorage wxOpenConfigStorage() {
        WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
        wxMpInMemoryConfigStorage.setAppId(accountConfig.getOpenAppId());
        wxMpInMemoryConfigStorage.setSecret(accountConfig.getOpenAppSecret());
        return wxMpInMemoryConfigStorage;
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WeChatController {
    private WxMpService wxMpService;
    private WxMpService wxOpenService;
    @GetMapping("/qrAuthorize")
    public String qrAuthorize() {
        //returnUrl就是用户授权同意后回调的地址
        String returnUrl = "http://heng.nat300.top/sell/wechat/qrUserInfo";
        //引导用户访问这个链接,进行授权
        String url = wxOpenService.buildQrConnectUrl(returnUrl, WxConsts.QRCONNECT_SCOPE_SNSAPI_LOGIN, URLEncoder.encode(returnUrl));
        return "redirect:" + url;
    //用户授权同意后回调的地址,从请求参数中获取code
    @GetMapping("/qrUserInfo")
    public String qrUserInfo(@RequestParam("code") String code) {
        WxMpOAuth3AccessToken wxMpOAuth3AccessToken = new WxMpOAuth3AccessToken();
        try {
            //通过code获取access_token
            wxMpOAuth3AccessToken = wxOpenService.oauth3getAccessToken(code);
        } catch (WxErrorException e) {
            log.error("【微信网页授权】{}", e);
            throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg());
        }
        //从token中获取openid
        String openId = wxMpOAuth3AccessToken.getOpenId();
        //这个地址可有可无,反正只是为了拿到openid,但是如果没有会报404错误,为了好看随便返回一个百度的地址
        String  returnUrl = "http://www.baidu.com";
        log.info("openid={}", openId);
        return "redirect:" + returnUrl + "?openid="+openId;

请求路径:在浏览器打开

https://open.weixin.qq.com/connect/qrconnect?appid=wx6ad144e54af67d87&redirect_uri=http%3A%2F%2Fsell.SpringBoot.cn%2Fsell%2Fqr%2FoTgZpwenC6lwO2eTDDf_-UYyFtqI&response_type=code&scope=snsapi_login&state=http%3A%2F%2Fheng.nat300.top%2Fsell%2Fwechat%2FqrUserInfo

获取了openid:openid=o9AREv7Xr22ZUk6BtVqw82bb6AFk

3. 用户登录和登出

@Controller
@RequestMapping("/seller")
public class SellerUserController {

    @Autowired
    private SellerService sellerService;
    private StringRedisTemplate redisTemplate;
    private ProjectUrlConfig projectUrlConfig;
    @GetMapping("/login")
    public ModelAndView login(@RequestParam("openid") String openid,                               HttpServletResponse response,                               Map<String, Object> map) {
        //1. openid去和数据库里的数据匹配
        SellerInfo sellerInfo = sellerService.findSellerInfoByOpenid(openid);
        if (sellerInfo == null) {
            map.put("msg", ResultEnum.LOGIN_FAIL.getMessage());
            map.put("url", "/sell/seller/order/list");
            return new ModelAndView("common/error");
        }
        //2. 设置token至redis
        String token = UUID.randomUUID().toString();
        //设置token的过期时间
        Integer expire = RedisConstant.EXPIRE;
        redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFIX, token), openid, expire, TimeUnit.SECONDS);
        //3. 设置token至cookie
        CookieUtil.set(response, CookieConstant.TOKEN, token, expire);
        return new ModelAndView("redirect:" + "http://heng.nat300.top/sell/seller/order/list");
    }
    @GetMapping("/loGout")
    public ModelAndView logout(HttpServletRequest request,                        HttpServletResponse response,                        Map<String, Object> map) {
        //1. 从cookie里查询
        Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
        if (cookie != null) {
            //2. 清除redis
            redisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));
            //3. 清除cookie
            CookieUtil.set(response, CookieConstant.TOKEN, null, 0);
        map.put("msg", ResultEnum.LOGOUT_SUCCESS.getMessage());
        map.put("url", "/sell/seller/order/list");
        return new ModelAndView("common/success", map);
}

① 将上一步获取到的openid存入数据库

② 将授权后跳转的地址改为登录地址

 //用户授权同意后回调的地址,从请求参数中获取code
    @GetMapping("/qrUserInfo")
    public String qrUserInfo(@RequestParam("code") String code) {
        WxMpOAuth3AccessToken wxMpOAuth3AccessToken = new WxMpOAuth3AccessToken();
        try {
            //通过code获取access_token
            wxMpOAuth3AccessToken = wxOpenService.oauth3getAccessToken(code);
        } catch (WxErrorException e) {
            log.error("【微信网页授权】{}", e);
            throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg());
        }
        //从token中获取openid
        String openId = wxMpOAuth3AccessToken.getOpenId();

        //授权成功后跳转到卖家系统的登录地址
        String  returnUrl = "http://heng.nat300.top/sell/seller/login";
        log.info("openid={}", openId);
        return "redirect:" + returnUrl + "?openid="+openId;
    }

③ 在浏览器请求这个链接:

https://open.weixin.qq.com/connect/qrconnect?appid=wx6ad144e54af67d87&redirect_uri=http%3A%2F%2Fsell.springboot.cn%2Fsell%2Fqr%2FoTgZpwenC6lwO2eTDDf_-UYyFtqI&response_type=code&scope=snsapi_login&state=http%3a%2f%2fheng.nat300.top%2fsell%2fwechat%2fqrUserInfo

第三应用请求使用微信扫码登录,而不是使用本网站的密码:

用户同意授权后登入第三方应用的后台管理系统:

4. Spring AOP校验用户有没有登录

@Aspect
@Component
@Slf4j
public class SellerAuthorizeAspect {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Pointcut("execution(public * com.hh.controller.Seller*.*(..))" +
    "&& !execution(public * com.hh.controller.SellerUserController.*(..))")
    public void verify() {}
    @Before("verify()")
    public void doVerify() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //查询cookie
        Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
        //如果cookie中没有token说明已经登出或者根本没有登录
        if (cookie == null) {
            log.warn("【登录校验】Cookie中查不到token");
            //校验不通过,抛出异常
            throw new SellerAuthorizeException();
        }
        //去redis里查询
        String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));
        //如果redis中没有对应的openid,同样表示登出或者根本没有登录
        if (StringUtils.isEmpty(tokenValue)) {
            log.warn("【登录校验】Redis中查不到token");
    }
}

5. 拦截登录校验不通过抛出的异常

拦截及登录校验不通过的异常,让其跳转到登录页面,扫码登录

@ControllerAdvice
public class SellExceptionHandler {
    //拦截登录异常
    @ExceptionHandler(value = SellerAuthorizeException.class)     public ModelAndView handlerAuthorizeException() {
        //拦截异常后,跳转到登录界面
        return new ModelAndView("redirect:".concat("https://open.weixin.qq.com/connect/qrconnect?" +
                "appid=wx6ad144e54af67d87" +
                "&redirect_uri=http%3A%2F%2Fsell.springboot.cn%2Fsell%2Fqr%2F" +
                "oTgZpwenC6lwO2eTDDf_-UYyFtqI" +
                "&response_type=code&scope=snsapi_login" +
                "&state=http%3a%2f%2fheng.nat300.top%2fsell%2fwechat%2fqrUserInfo"));
    }
    @ExceptionHandler(value = SellException.class)     @ResponseBody     public ResultVO handlerSellerException(SellException e) {
        return ResultVOUtil.error(e.getCode(), e.getMessage());
    }
    @ExceptionHandler(value = ResponseBankException.class)     @ResponseStatus(HttpStatus.FORBIDDEN)     public void handleResponseBankException() {
    }
}

到此这篇关于Spring Boot 实现微信扫码登录的文章就介绍到这了,更多相关Spring Boot微信扫码登录内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Spring Boot实现微信扫码登录功能流程分析

本文链接: https://www.lsjlt.com/news/146955.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring Boot实现微信扫码登录功能流程分析
    目录1. 授权流程说明第一步:请求CODE第二步:通过code获取access_token第三步:通过access_token调用接口2. 授权流程代码3. 用户登录和登出4. Sp...
    99+
    2022-11-13
  • Spring Boot怎么实现微信扫码登录功能
    本文小编为大家详细介绍“Spring Boot怎么实现微信扫码登录功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring Boot怎么实现微信扫码登录功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一...
    99+
    2023-06-30
  • Spring Boot实现微信小程序登录
    使用Spring Boot完成微信小程序登录 由于微信最近的版本更新,wx.getUserInfo()的这个接口即将失效,将用wx.getUserProfile()替换,所以近期我也...
    99+
    2022-11-12
  • 企业微信扫码登录网页功能实现代码
    企业微信扫码登录网页功能,代码如下所示: //jq写法完善版 <!DOCTYPE html> <html lang="en"> <head> ...
    99+
    2022-11-13
  • 如何使用PHP实现微信扫码登录功能
    随着移动互联网的快速发展,微信作为一种重要的社交工具,已经逐渐成为人们日常生活中必不可少的一个部分。在许多网站和应用程序中,微信登录功能已经成为了一种趋势,因为它可以让用户直接使用已有的微信账号来登录,不需要再创建新的账户,同时也能提供更便...
    99+
    2023-05-14
    微信扫码登录 php
  • 怎么使用PHP实现微信扫码登录功能
    这篇文章主要讲解了“怎么使用PHP实现微信扫码登录功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用PHP实现微信扫码登录功能”吧!一、准备工作在开始实现微信扫码登录功能之前,我们需...
    99+
    2023-07-05
  • PHP实现微信关注公众号扫码登录功能
    PHP微信扫码登录看起来简单,但做起来有点复杂,微信接口的坑有点多,稍不注意,就费很多时间。PHP判断是否首次关注公众号,扫码关注公众号获取微信用户头像、openid和省市等信息源码。        ...
    99+
    2023-06-05
  • PHP实现微信扫码登录功能的两种方式总结
    官方文档 微信扫码登录目前有两种方式: 1:在微信作用域执行 ,就是条一个新页面 前端点击一个按钮,请求后端接口条微信作用域 后端php代码如下: $redirect_ur...
    99+
    2022-11-13
  • 扫微信小程序码实现网站登陆的示例分析
    这篇文章主要介绍扫微信小程序码实现网站登陆的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!使用扫小程序码登陆网站思路核心流程关键流程建立场景sceneid和websocket...
    99+
    2022-10-19
  • 基于 antd pro 的短信验证码登录功能(流程分析)
    目录概要整体流程前端页面代码请求验证码和登录的 service (src/services/login.js)处理登录的 model (src/models/login.js)后端短...
    99+
    2022-11-12
  • Spring Boot实现登录验证码功能的案例详解
    目录验证码的作用案例要求前端页面准备准备login.html页面随机验证码工具类后端控制器验证码的作用 验证码的作用:可以有效防止其他人对某一个特定的注册用户用特定的程序暴力破解方式...
    99+
    2022-11-13
    springboot登录验证码 springboot验证码
  • java微信扫描公众号二维码实现登陆功能
    本文实例为大家分享了java微信扫描公众号二维码实现登陆的具体代码,供大家参考,具体内容如下前提条件: 微信公众平台为服务号, 2.服务号实现了账号绑定功能,即将open_id 与业务系统中的用户名有对应关系具体实现原理: 用户访问业务系统...
    99+
    2023-05-31
    java 二维码
  • 微信小程序怎样实现登录功能
    这篇文章主要介绍了微信小程序怎样实现登录功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。微信小程序登录一. 小程序不支持cookie会话 ...
    99+
    2022-10-19
  • 网站使用微信小程序扫码登录的实现方法
    前言 传统网站一般都会使用账号密码登录,但这种方式总有用户会忘记密码,找回密码需要一系列验证,也挺麻烦的,于是学习了一下扫码登录,这种方式不仅不会有忘记密码的烦恼,登录还十分快捷。用户体验较好. ...
    99+
    2023-09-20
    微信小程序 小程序 前端
  • 使用微信小程序实现二维码扫描功能
    使用微信小程序实现二维码扫描功能随着移动互联网的快速发展,二维码已经成为了一种非常方便的信息交互方式。微信小程序作为一种新的应用形式,也提供了二维码扫描功能。本文将介绍如何使用微信小程序实现二维码扫描,并提供具体的代码示例。一、准备工作在开...
    99+
    2023-11-21
    二维码 微信小程序 扫描
  • 【微信授权登录】uniapp开发小程序,实现获取微信授权登录功能
    一、解题思路: 微信授权登录(获取用户信息) 1.先获取用户信息——用户授权允许后,通过调用uni.login 可以获取到code。 2.拿着获取到的code去调用——登录接口,可以获取到token。 3.把token存入缓存。就可以在页面...
    99+
    2023-08-16
    小程序 微信 javascript
  • 微信小程序授权登录功能如何实现
    这篇文章主要介绍“微信小程序授权登录功能如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“微信小程序授权登录功能如何实现”文章能帮助大家解决问题。微信授权登录我们的项目开发有时候用到用户的一些信...
    99+
    2023-07-05
  • 微信小程序登录与注册功能的实现详解
    目录小程序中的登录用户注册用户信息修改总结小程序中的登录 在小程序中有一个概念叫openid,这个相当于登录小程序用户的唯一标识,每个微信用户都不同。那要如何拿到用户的唯一标识呢?在...
    99+
    2022-11-13
    微信小程序登录 微信小程序注册
  • Django + Taro 前后端分离项目实现企业微信登录功能
    目录前言两种方式思路后端代码企业微信应用配置前端代码参考资料前言 还是最近在做的一个小项目,后端用的是Django搭配RestFramework做接口,前端第一次尝试用京东开源的Ta...
    99+
    2022-11-10
  • Java后台实现网站微信扫码登录功能,获取用户openid,及微信用户信息(小程序码方案),关联微信小程序(个人主体小程序也可以)
    目录 目录 前言 下面展示操作流程 注册微信小程序 通过后台获取小程序码 前端处理 时序图理解 方案实现步骤 前言 很多业务场景之下我们需要实现 微信扫码登录 的需求,如: 同步网站与小程序的用户数据。需要获取用户微信相关基本信息,...
    99+
    2023-09-02
    小程序 微信 微信小程序
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作