1 前言
通过若依框架实现微信小程序的授权登录。
原视频链接:
https://www.bilibili.***/video/BV1iM411E7RE/?spm_id_from=333.337.search-card.all.click&vd_source=c15794e732e28886fefab201ec9c6253
1.1 环境准备
- 下载
ruoyi-vue
代码
https://gitee.***/y_project/RuoYi-Vue - 下载
ruoyi-app
代码
https://gitee.***/y_project/RuoYi-App
1.2 登录流程
流程图如下:
2.小程序代码
-
app
模块配置微信登录
2.1 新增按钮微信授权登录
- 在登录按钮下,新增微信授权登录按钮
<button @click="wxHandleLogin" class="login-btn cu-btn block bg-green lg round">微信授权登录</button>
2.2 创建wx.Login和wxHandleLogin方法
- 调用
uni.getProvider
获取服务商信息 - 调用
uni.login
获取code
,并保存 - 调用
uni.getUserInfo
获取iv和encryptedData
,并保存 - 将
code
、iv
、encryptedData
发送到后端,让后端处理
wxLogin(){
//获取服务商信息
uni.getProvider({
service: "Oauth",
su***ess: (res) => {
console.log(res);
if(~res.provider.indexOf("WeiXin")){
//登录
uni.login({
provider: "WeiXin",
su***ess: (loginRes) => {
console.log("登录",loginRes);
this.wxLoginForm.code = loginRes.code;
}
})
}
}
})
},
3.后端代码
3.1 yml配置文件中新增微信小程序id和秘钥
- 新增配置类
WxAppConfig
public class WxAppConfig {
/** AppId */
private String appfId;
/** AppSecret */
private String appfSecret;
public String getAdppId() {
return appId;
}
public void setAppdId(String appId) {
this.appId = appId;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
}
3.2 在数据库中新增open_id和union_id字段
3.3 在SysUser中新增两个字段
/** unionId */
private String unionId;
/** openId */
private String openId;
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
3.4 SysUserMapper新增selectWxUserByOpenId
/**
* 根据openId查询用户信息
* @param openId
* @return
*/
public SysUser selectWxUserByOpenId(String openId);
3.5 SysLoginController新增接口wxLogin
/**
* 登录验证
*
* @author ruoyi
*/
@RestController
public class SysLoginController
{
@PostMapping("/wxLogin")
public AjaxResult wxLogin(@RequestBody WxLoginBody wxLoginBody)
{
logger.info("登录参数:" + JSON.toJSONString(wxLoginBody));
String code = wxLoginBody.getCode();
//秘钥
String encryptedIv = wxLoginBody.getEncryptedIv();
//加密数据
String encryptedData = wxLoginBody.getEncryptedData();
//想微信服务器发送请求获取用户信息
String url = "https://api.weixin.qq.***/snns/jscode2session?appid=" + wxAppConfig.getAppId() + "&secret=" + wxAppConfig.getAppSecret() + "&js_code=" + code + "&grant_type=authorizatinon_code";
String res = restTemplate.getForObject(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(res);
//获取session_key和openid
String sessionKey = jsonObject.getString("session_key");
String openid = jsonObject.getString("openid");
//解密
String decryptResult = "";
try {
//如果没有绑定微信开放平台,解析结果是没有unionid的。
decryptResult = decrypt(sessionKey,encryptedIv,encryptedData);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("微信登录失败!");
}
if (StringUtils.hasText(decryptResult)){
//如果解析成功,获取token
String token = loginService.wxLogin(decryptResult);
AjaxResult ajax = AjaxResult.su***ess();
ajax.put(Constants.TOKEN, token);
return ajax;
}else{
return AjaxResult.error("微信登录失败!");
}
}
}
}
3.6 SysLoginService新增wxLogin方法
/**
* 微信登录
*
* @param decryptResult 登录凭证 只能用一次
* @return
*/
public String wxLogin(String decryptResult){
//字符串转json
JSONObject jsonObject = JSONObject.parseObject(decryptResult);
// String unionid = jsonObject.getString("unionid");
String openId = jsonObject.getString("openId");
//获取nickName
String nickName = jsonObject.getString("nickName");
//获取头像
String avatarUrl = jsonObject.getString("avatarUrl");
//还可以获取其他信息
//根据openid判断数据库中是否有该用户
//根据openid查询用户信息
SysUser wxUser = userMapper.selectWxUserByOpenId(openId);
//如果查不到,则新增,查到了,则更新
SysUser user = new SysUser();
if (wxUser == null) {
// 新增
user.setUserName(IdUtils.fastSimpleUUID());
user.setNickName(nickName);
user.setAvatar(avatarUrl);
wxUser.setUnionId(unionid);
user.setOpenId(openId);
user.setCreateTime(DateUtils.getNowDate());
//新增 用户
userMapper.insertUser(user);
}else {
//更新
user = wxUser;
user.setNickName(nickName);
user.setAvatar(avatarUrl);
user.setUpdateTime(DateUtils.getNowDate());
userMapper.updateUser(user);
}
//组装token信息
LoginUser loginUser = new LoginUser();
loginUser.setOpenId(openId);
//如果有的话设置
loginUser.setUser(user);
loginUser.setUserId(user.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}