先了解下SSO

对于单点登陆浅显一点的说就是两种,一种web端的基于Cookie、另一种是跨端的基于Token,一般想要做的都优先做Token吧,个人建议,因为后期扩展也方便哦。

小程序也是呢,做成token的形式是较好的。

流程图


PS:图中4的文字打错了~

1、启动服务
2、小程序初次加载app.js校验token,使用code去换取token
3、检测User信息是否存在code,不存在则注册新用户,最后返回对应用户Id
4、将随机Token与UserId一起存入Redis中
5、返回Token信息,小程序存于缓存中,作为api请求的认证凭证

这个流程思路对什么后台语言都是通用的。

具体实现

本文的环境主要是做SpringBoot的,所有对于其他框架可能没有很好的兼容。

直接上代码弄起来吧!

首先是开源的话,我们需要确定某些东西是一定要配置的,不能写死。那么我写了两个Config类来获取application.yml中的数据,不同用户可以配置他们的参数。

wechat:
wxurl: https://api.weixin.qq.com/sns/jscode2session?
appid: wxabc2f8828c8e0049
appsecret: cec2412a3af99200f4573c337715329a
granttype: authorization_code
redis:
expire: 7200
wxtoken: wx_token_%s
spring:
redis:
port: 6379
host: 192.168.192.132

我这边了以上的参数作为组件中的可配置,其实部分可以作为默认的,不过暂时没有改了,如果你像要使用就是暂时都是必选的。

项目目录


config包中的就是对配置参数的读取。

utils包是存放一个Http的请求工具。

最核心的就是我们的WechatTemplate类了。

根据业务,我们需要以下几个方法:

根据小程序传递来的code获取openid

/**
* 获取OpenId
* @param code 微信code
* @return {@link Map}
*/
public Map<String,String> getOpenId(String code){
Map<String,String> back = new HashMap<>();
Map<String,String> wxResult = new HashMap<>();
String wxLoginUrl = weChatComponent.url(code);
String result = HttpServiceUtils.sendGet(wxLoginUrl);
if (result.isEmpty()){
back.put("null","null");
}else{
wxResult = (Map) JSON.parse(result);
if (wxResult.containsKey("errCode")){
//存在错误码
back.put("errCode",wxResult.get("errCode"));
}else{
//不存在错误码
String session_key = wxResult.get("session_key");
back.put("session_key",session_key);
log.info("【微信Token】session_key:"+session_key);
String openid = wxResult.get("openid");
back.put("openid",openid);
}
}
return back;
}

根据openid,我们可以和数据库对接得到用户id并生成自己Token

/**
* 生成Token
* @param userid 用户id
* @return {@link String}
*/
public String granToken(String userid){
return saveToRedis(userid);
} /**
* 获取Token并存放到redis中
* @param userid 用户id
* @return {@link String}
*/
private String saveToRedis(String userid) {
String token = UUID.randomUUID().toString();
Integer expire = redisComponent.getExpire();
redisTemplate.opsForValue().set(String.format(redisComponent.getWxtoken(),token),userid,expire, TimeUnit.SECONDS);
return token;
}

还有校验Token,是否存在

/**
* 校验是否存在用户信息
* @param token 唯一值
* @return {@link Boolean}
*/
public boolean verifyToken(String token){
String tokenValue = redisTemplate.opsForValue().get(String.format(redisComponent.getWxtoken(),token));
if (tokenValue.isEmpty()){
return false;
}
return true;
}

Maven包

接着打包发到Maven中央仓库中,生成自己的maven包

<dependency>
<groupId>com.github.UncleCatMySelf</groupId>
<artifactId>wechat-login</artifactId>
<version>2.1.0</version>
</dependency>

如何使用?

我在Github项目中,做了Demo演示。

我们仅需在Service中调用,并使用对应方法即可。

@Slf4j
@Service
public class UserServiceImpl implements UserService { @Autowired
private WechatTemplate wechatTemplate; @Autowired(required = true)
private ResultVOUtil resultVOUtil; @Override
public ResultVo getToken(String code) {
Map<String,String> result = wechatTemplate.getOpenId(code);
if (result.containsKey("null")){
return resultVOUtil.error(555,"返回值为空");
}else if(result.containsKey("errCode")){
return resultVOUtil.error(666,"存在错误码,内容:"+result.get("errCode"));
}else{
String sessionKey = result.get("session_key");
String openid = result.get("openid");
log.info("openid="+openid+"--sessionKey="+sessionKey);
//与存在用户的openid信息进行对比,返回用户id,不存在则注册用户
String userid = "WX_10agg";//模拟获取到的用户id
String token = wechatTemplate.granToken(userid);
return resultVOUtil.success(token);
}
} @Override
public ResultVo verifyToken(String token) {
return resultVOUtil.success(wechatTemplate.verifyToken(token));
}
}

tip:记得添加扫描包路径,@ComponentScan({“com.github.unclecatmyself”})

GitHub

wechat-login
一个配合小程序登录的前后台组件(Token形式),附带前端小程序代码

作者:UncleCatMySelf
链接:https://www.imooc.com/article/263335
来源:慕课网
本文首次发布于慕课网 ,转载请注明出处,谢谢合作


最新文章

  1. 掌握 Cinder 的设计思想 - 每天5分钟玩转 OpenStack(46)
  2. Node.js与Sails~Model数据模型
  3. 微信扫码支付asp.net(C#)实现步骤
  4. jQuery+css+div--一些细节详解
  5. js两种创建对象方式
  6. [RxJS] Stream Processing With RxJS vs Array Higher-Order Functions
  7. [LeetCode] Longest Palindrome Substring 具体分析
  8. NUnit详细使用方法
  9. HBase全分布安装配置
  10. hive metastore Server 出现异常
  11. 我们为什么需要SDN?---致新人
  12. Nexys3学习手记1:写在前面的话
  13. Enable multi-tenancy on ironic
  14. Eclipse Decompiler不生效解决办法
  15. PHP多进程实例
  16. 使用c#反射实现接口可视化调试页面
  17. 【转】Loadrunder场景设计篇——添加windows Resource计数器和指标说明
  18. sqli-labs:5-6,盲注
  19. Eclipse-安装Spring Tool Suit 插件
  20. Arduino和C51开发DHT11温湿度传感器

热门文章

  1. XSS之偷梁换柱--盲打垃圾短信平台
  2. 删除 id 列表 存进数据库
  3. 创建Jdbc封装工具类
  4. JDK 1.8判断集合种的元素是否存在相同
  5. fremarker导出word list
  6. 为什么 web 开发人员需要迁移到. NET Core, 并使用 ASP.NET Core MVC 构建 web 和 webservice/API
  7. PHPWord导出word文档
  8. [Swift]LeetCode61. 旋转链表 | Rotate List
  9. [Swift]LeetCode530. 二叉搜索树的最小绝对差 | Minimum Absolute Difference in BST
  10. [Swift]LeetCode686. 重复叠加字符串匹配 | Repeated String Match