Article directory
原视频链接
1 Introduction
Combine RuoYi-Cloud
and RuoYi-App
realize the authorized login of WeChat applet.
I talked about the authorized login of the front-end and back-end separate versions before, and the logic is roughly the same. The differences are:
- How to obtain WeChat profile picture and nickname. Due to the latest local library, the user's avatar
getUserProfile
andgetUserInfo
nickname cannot be obtained. Use the avatar nickname to fill in the function. (Remarks: https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01 ) - The micro-server uses
OpenFeign
remote calls, and fans who don’t know how to make remote calls can learn about it. YesFeign
, the bottom layer , and Zoe's . Compared with itself, it supports annotations, which is very convenient to use .Spring3.0
RestTemplate
RestTemplate
OkHttp
Feign
OpenFeign
Spring MVC
1.1 Environment preparation
- Download
RuoYi-Cloud
code
and add link description https://gitee.com/y_project/RuoYi-Cloud - Download
RuoYi-App
code
https://gitee.com/y_project/RuoYi-App
1.2 Login flow chart
2 applet code
- For WeChat developer tool base library
2.30.*
app
Module configuration WeChat login
- use your own
appid
2.1 RuoYi-App editing api/login.js
- Login, logout interface path plus
/auth
- Get user information interface path plus
/system
- Get the verification code interface path and replace it with
/code
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
'url': '/auth/login',
headers: {
isToken: false
},
'method': 'post',
'data': data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
'url': '/system/user/getInfo',
'method': 'get'
})
}
// 退出方法
export function logout() {
return request({
'url': '/auth/logout',
'method': 'delete'
})
}
// 获取验证码
export function getCodeImg() {
return request({
'url': '/code',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
}
2.4 Add button WeChat authorized login
- Under the login button, add a WeChat authorization login button
<button @click="wxHandleLogin" class="login-btn cu-btn block bg-green lg round">微信授权登录</button>
2.6 Add wxHandleLogin method to get code
// 微信登录
async wxHandleLogin() {
uni.getProvider({
service:'Oauth',
success: (res) => {
console.log(res);
if(res.provider.indexOf("WeiXin")){
//登录
uni.login({
provider:'WeiXin',
success: (loginRes) => {
}
})
}
}
})
}
2.9 Create sendWxLoginFormToLocalService method
//向本地服务发起请求
sendWxLoginFormToLocalService(){
console.log("向后端发起请求" + this.wxLoginForm);
this.$store.dispatch('wxLogin', this.wxLoginForm).then(() => {
this.$modal.closeLoading()
}).catch(() => {
})
}
3 Microservice Code
3.5 auth service TokenController add interface wxLogin
public R<?> wxLogin(@RequestBody WxLoginBody wxLoginBody){
String code = wxLoginBody.getCode();
//想微信服务器发送请求获取用户信息
String url = "https://api.weixin.qq.com/sns/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");
if (StringUtils.hasText(openid)){
// 如果解析成功,获取token
LoginUser userInfo = sysLoginService.wxLogin(openid);
// 获取登录token
return R.ok(tokenService.createToken(userInfo));
}else{
return R.fail("微信登录失败!");
}
}
3.7 The ruoyi-api module adds remote calls
/**
* 通过openid查询用户信息
*
* @param openid openid 用户唯一标识
* @param source 请求来源
* @return 结果
*/
@GetMapping("/user/getInfoByOpenid/{openid}")
public R<LoginUser> getInfoByOpenid(@PathVariable("openid") String openid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
3.9 System service SysUserController adds internal interfaces getInfoByOpenid and addWxUser
- database addition
unionId
andopenId
- domain (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;
}
- controller 层(SysUserController)
/**
* 根据openid获取当前用户信息
*/
public R<LoginUser> getInfoByOpenid(@PathVariable("openid") String openid)
{
SysUser sysUser = userService.selectUserByOpenid(openid);
LoginUser sysUserVo = new LoginUser();
if (StringUtils.isNull(sysUser))
{
sysUserVo.setSysUser(null);
return R.ok(sysUserVo);
}
return R.ok(sysUserVo);
}
/**
* 新增微信用户信息
*/
public R<SysUser> addWxUser(@RequestBody SysUser sysUser)
{
String username = sysUser.getUserName();
userService.insertWxUser(sysUser);
return R.ok(sysUser);
}
- service layer (SysUserServiceImpl)
interface:
/**
* 通过openid查询用户
*
* @param openid 用户唯一标识
* @return 用户对象信息
*/
public SysUser selectUserByOpenid(String openid);
/**
* 新增微信用户信息
*
* @param user 用户信息
* @return 结果
*/
public int insertWxUser(SysUser user);
Implementation class:
/**
* 通过openid查询用户
*
* @param openid 用户唯一标识
* @return 用户对象信息
*/
@Override
public SysUser selectUserByOpenid(String openid)
{
return userMapper.selectUserByOpenid(openid);
}
/**
* 新增微信用户信息
*
* @param user 用户信息
* @return 结果
*/
@Override
public int insertWxUser(SysUser user)
{
// 新增用户信息
return userMapper.insertUser(user);
}
mapper 山 (SysUserMapper)
/**
* 通过openid查询用户
*
* @param openid 用户唯一标识
* @return 用户对象信息
*/
public SysUser selectUserByOpenid(String openid);
mybatis.xml (SysUserMapper.xml)
u.union_id, u.open_id,
....
<select id="selectUserByOpenid" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.open_id = #{openId} and u.del_flag = '0'
</select>
....
<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
insert into sys_user(
<if test="userId != null and userId != 0">user_id,</if>
<if test="deptId != null and deptId != 0">dept_id,</if>
<if test="userName != null and userName != ''">user_name,</if>
<if test="nickName != null and nickName != ''">nick_name,</if>
<if test="email != null and email != ''">email,</if>
<if test="avatar != null and avatar != ''">avatar,</if>
<if test="phonenumber != null and phonenumber != ''">phonenumber,</if>
<if test="sex != null and sex != ''">sex,</if>
<if test="password != null and password != ''">password,</if>
<if test="status != null and status != ''">status,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="openId != null and openId != ''">open_id,</if>
<if test="unionId != null and unionId != ''">union_id,</if>
create_time
)values(
<if test="userId != null and userId != ''">#{userId},</if>
<if test="deptId != null and deptId != ''">#{deptId},</if>
<if test="userName != null and userName != ''">#{userName},</if>
<if test="nickName != null and nickName != ''">#{nickName},</if>
<if test="email != null and email != ''">#{email},</if>
<if test="avatar != null and avatar != ''">#{avatar},</if>
<if test="phonenumber != null and phonenumber != ''">#{phonenumber},</if>
<if test="sex != null and sex != ''">#{sex},</if>
<if test="password != null and password != ''">#{password},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="openId != null and openId != ''">#{openId},</if>
<if test="unionId != null and unionId != ''">#{unionId},</if>
sysdate()
)
</insert>