1. 前言

原本打算把Spring SecurityOAuth 2.0的机制讲完后,用小程序登录来实战一下,发现小程序登录流程和Spring SecurityOAuth 2.0登录的流程有点不一样,就把写了半天的东西全部推翻了。但是,但是过了一天之后,突然感觉又可以了。我们来一起试一试。

2. 小程序登录流程分析

小程序的登录流程是这样的:

而在Spring Security中的OAuth 2.0 Code模式是这样的:

从这两张图上看最大的差别就是微信小程序中获取code不需要通过后端服务器的调用,而Spring Security中需要(第1步,第2步,第3步)。腾讯应该也是借鉴了OAuth 2.0,但是做了一些改动。

让我放弃的也是这个差别,有没有人能想到解决方法呢?

假如说小程序已经持有了code,它依然需要将code传递给后端服务器来执行后面的流程。那么我们能不能利用图2中第3个调用redirectUri的步骤呢?换个角度来看问题第三方就是小程序反正它也是将一个code传递给了后端服务器,只要返回登录状态就行了,反正剩下的登录流程都跟小程序无关。我觉得它是可以的。在Spring Security中我们可以使用code通过tokenUri来换取token。那么在微信小程序登录流程中,code最终换取的只是登录态,没有特定的要求。但是后端肯定需要去获取用户的一些信息,比如openId,用户微信信息之类的。总之要根据微信平台提供的API来实现。通过改造tokenUriuserInfoUri可以做到这一点。

3. 思路借鉴

所有的猜想都没有错,而且我也实现了,但是改造成本过高了,写了很多兼容性的代码,如果不深入Spring Security,很难实现这,而且也不好理解。

为了简化实现,我决定借鉴Spring SecurityOAuth 2.0的思路。Filter拦截小程序登录URL,然后通过RestTemplate执行向微信服务器请求获取结果,处理后返回登录态。时序图如下:

对应的伪代码实现:

package cn.felord.spring.security.filter;

import org.springframework.http.ResponseEntity;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.UriComponentsBuilder; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI; /**
* 小程序登录过滤器
*
* @author felord.cn
* @since 1.0.4.RELEASE
*/
public class WeChatAppLoginFilter extends OncePerRequestFilter { private final RequestMatcher requiresAuthenticationRequestMatcher;
private final RestTemplate restTemplate;
private String appId;
private String secret;
private static final String WX_URL = "https://api.weixin.qq.com/sns/jscode2session"; public WeChatAppLoginFilter(String loginProcessingUrl, String appId, String secret) {
this.appId = appId;
this.secret = secret;
Assert.notNull(loginProcessingUrl, "loginProcessingUrl must not be null");
this.requiresAuthenticationRequestMatcher = new AntPathRequestMatcher(loginProcessingUrl, "POST");
this.restTemplate = new RestTemplate();
} @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 拦截微信登录
if (requiresAuthenticationRequestMatcher.matches(request)) {
//todo 从request中获取 code 参数 这里逻辑根据你的情况自行实现
String jsCode = "你自行实现从request中获取";
//todo 必要的校验自己写
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
queryParams.add("appid", this.appId);
queryParams.add("secret", this.secret);
queryParams.add("js_code", jsCode);
queryParams.add("grant_type", "authorization_code"); URI uri = UriComponentsBuilder.fromHttpUrl(WX_URL)
.queryParams(queryParams)
.build()
.toUri();
//todo 这里 Object 自行封装为具体对象
ResponseEntity<Object> result = this.restTemplate.getForEntity(uri, Object.class); //todo 处理 result 比如后端存储、后端授权、角色资源处理、注册、对session_key的处理等等你需要的业务逻辑
// 最后放入HttpServletResponse中返回前端返回 } else {
filterChain.doFilter(request, response);
}
}
}

最后一定别忘了把过滤器配置到WebSecurityConfigurerAdapterHttpSecurity中去。

4. 总结

本篇讲解了Spring Security和微信小程序登录相结合的思路历程。本来不需要长篇大论OAuth 2.0,之所以写出来是让你明白开发中要善于发现一些相似的东西,通过差异对比来探讨他们结合的可能性,这也是一种自我提升的方法。方法远比结果重要,形成自己的方法论就能富有创造力。我是:码农小胖哥,多多关注,分享更多原创编程干货。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

Spring Security 整合 微信小程序登录的思路探讨的更多相关文章

  1. 基于Shiro,JWT实现微信小程序登录完整例子

    小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html ...

  2. 微信小程序登录JAVA后台

    代码地址如下:http://www.demodashi.com/demo/12736.html 登录流程时序登录流程时序 具体的登录说明查看 小程序官方API 项目的结构图: springboot项目 ...

  3. Spring Security 整合freemaker 实现简单登录和角色控制

    Spring Security 整合freemaker 实现简单登录和角色控制     写这篇文章是因为我做了一个电商网站项目,近期刚加上权限控制.整个过程很简单,在此给大家梳理一下,也算是自己对知识 ...

  4. 微信小程序登录方案

    微信小程序登录方案 登录程序 app.js 调用wx.login获取code 将code作为参数请求自己业务登录接口获取session_key 存储session_key 如果有回调执行回调 App( ...

  5. 微信小程序登录,获取code,获取openid,获取session_key

    微信小程序登录 wx.login(Object object) 调用接口获取登录凭证(code).通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session ...

  6. 微信小程序登录对接Django后端实现JWT方式验证登录

    先上效果图 点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料. 流程 1.使用微信小程序登录和获取用户信息Api接口 2.把Api获取的用户资料和code发送给django后端 3. ...

  7. 全栈项目|小书架|微信小程序-登录及token鉴权

    小程序登录 之前也写过微信小程序登录的相关文章: 微信小程序~新版授权用户登录例子 微信小程序-携带Token无感知登录的网络请求方案 微信小程序开通云开发并利用云函数获取Openid 也可以通过官方 ...

  8. Flask与微信小程序登录(后端)

    开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + flask + 微信小程序实现用户快速注册登录方案(本文主要进行后 ...

  9. Taro -- 微信小程序登录

    Taro微信小程序登录 1.调用Taro.login()获取登录凭证code: 2.调用Taro.request()将code传到服务器: 3.服务器端调用微信登录校验接口(appid+appsecr ...

随机推荐

  1. ZeptoLab Code Rush 2015 B. Om Nom and Dark Park

    Om Nom is the main character of a game "Cut the Rope". He is a bright little monster who l ...

  2. Fiddler+雷电模拟器进行APP抓包

    1.下载最新版Fiddler,强烈建议在官网下载:https://www.telerik.com/download/fiddler 2. 正常傻瓜式安装,下一步,下一步,安装完毕后,先不用急于打开软件 ...

  3. 分布式一致性算法 2PC 3PC Paxos

    分布式一致性算法的目的是为了解决分布式系统 一致性算法可以通过共享内存(需要锁)或者消息传递实现,本文讨论后者实现的一致性算法,不仅仅是分布式系统中,凡是多个过程需要达成某种一致的场合都可以使用. 本 ...

  4. 微信小程序swiper实现 句子控app首页滑动卡片

    微信小程序swiper实现 句子控app首页滑动卡片 引言:最近看到句子控APP首页的效果很清新,可是发现他的微信小程序端没有实现这个功能,我看了一下难度不大,于是尝试着去实现. 实现效果如下: 1. ...

  5. SpringBoot引入openfeign 报错:spring-cloud-starter-openfeign:unknown

    现象: 1.maven报错:Cannot resolve org.springframework.cloud:spring-cloud-starter-openfeign:unknown 解决: 在h ...

  6. Spring Cloud实战 | 第十一篇:Spring Cloud Gateway 网关实现对RESTful接口权限控制和按钮权限控制

    一. 前言 hi,大家好,这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT实现的统 ...

  7. kubernetes进阶(一) kubectl工具使用详解

    管理k8s核心资源的三种基本方法: 一.陈述式-主要依赖命令行工具  --可以满足90%以上的使用场景,但是缺点也很明显: 命令冗长,复杂,难以记忆 特定场景下,无法实现管理需求 对资源的增.删.查操 ...

  8. 牛客网-Beautiful Land 【01背包 + 思维】

    链接:https://www.nowcoder.com/acm/contest/119/F来源:牛客网 Now HUST got a big land whose capacity is C to p ...

  9. HDU - 4455 Substrings(非原创)

    XXX has an array of length n. XXX wants to know that, for a given w, what is the sum of the distinct ...

  10. IP的地址的划分

    IP地址的划分是计算机网络中很重要的一个知识点,曾经考过三级,但是长时间不用就会忘掉,现在重新将IP的地址划分整理一遍. 首先IP地址的编址方法经历了三个阶段:分类的IP地址.子网的划分.构成超网 我 ...