1、创建一个前端APP用户表:app_user表,并插入一条数据
DROP TABLE IF EXISTS `app_user`;
CREATE TABLE `app_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`user_name` varchar(30) NOT NULL COMMENT '用户账号',
`nick_name` varchar(30) NOT NULL COMMENT '用户昵称',
`email` varchar(50) DEFAULT '' COMMENT '用户邮箱',
`mobile` varchar(11) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' COMMENT '手机号码',
`sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
`avatar` varchar(100) DEFAULT '' COMMENT '头像地址',
`password` varchar(100) DEFAULT '' COMMENT '密码',
`salt` varchar(50) DEFAULT '' COMMENT '盐',
`status` char(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
/*Data for the table `app_user` */
insert into `app_user`(`user_id`,`user_name`,`nick_name`,`email`,`mobile`,`sex`,`avatar`,`password`,`salt`,`status`,`del_flag`,`login_ip`,`login_date`,`create_by`,`create_time`,`update_by`,`update_time`,`remark`) values (1,'qiaochu666','翘楚','123456@163.com','18866778899','1','','bb6d30fe528388b8f08631afb5a22c5c','GoEskKGp','0','0','192.168.3.4','2023-10-28 21:48:46','管理员','2023-10-28 21:24:06','管理员','2023-10-28 21:48:46','测试账号');
2、创建 AppUser 实体类
package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.core.domain.BaseEntity;
import java.util.Date;
/**
* 用户对象 app_user
*
* @author ruoyi
*/
public class AppUser extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 用户账号
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户邮箱
*/
private String email;
/**
* 手机号码
*/
private String mobile;
/**
* 用户性别(0=男,1=女,2=未知)
*/
private String sex;
/**
* 用户头像
*/
private String avatar;
/**
* 密码
*/
private String password;
/**
* 盐
*/
private String salt;
/**
* 帐号状态(0=正常,1=停用)
*/
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 最后登录IP
*/
private String loginIp;
/**
* 最后登录时间
*/
private Date loginDate;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getLoginIp() {
return loginIp;
}
public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
}
public Date getLoginDate() {
return loginDate;
}
public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
}
目录:ruoyi-common——>src——>main——>java——>com.ruoyi.common——>core——>domian——>entity
注意:与 SysUser 同级目录
3、创建 AppUserMapper.xml 映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.AppUserMapper">
<resultMap type="AppUser" id="AppUserResult">
<id property="userId" column="user_id"/>
<result property="userName" column="user_name"/>
<result property="nickName" column="nick_name"/>
<result property="email" column="email"/>
<result property="mobile" column="mobile"/>
<result property="sex" column="sex"/>
<result property="avatar" column="avatar"/>
<result property="password" column="password"/>
<result property="salt" column="salt"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="loginIp" column="login_ip"/>
<result property="loginDate" column="login_date"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="selectAppUserVo">
select user_id, user_name, nick_name, email, avatar, mobile, password, salt, sex, status, del_flag, login_ip, login_date, create_by, create_time, remark from app_user
</sql>
<select id="selectAppUserByUserName" parameterType="String" resultMap="AppUserResult">
<include refid="selectAppUserVo"/>
where user_name = #{userName} and del_flag = '0'
</select>
<update id="updateAppUser" parameterType="AppUser">
update app_user
<set>
<if test="userName != null and userName != ''">user_name = #{userName},</if>
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
<if test="email != null ">email = #{email},</if>
<if test="mobile != null ">mobile = #{mobile},</if>
<if test="sex != null and sex != ''">sex = #{sex},</if>
<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
<if test="password != null and password != ''">password = #{password},</if>
<if test="salt != null and salt != ''">salt = #{salt},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if>
<if test="loginDate != null">login_date = #{loginDate},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = sysdate()
</set>
where user_id = #{userId}
</update>
</mapper>
目录:ruoyi-system——>src——>main——>resources——>mapper.system
注意:与 SysUserMapper.xml 同级目录
4、创建 AppUserMapper 数据层
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.domain.entity.AppUser;
/**
* 用户表 数据层
*
* @author ruoyi
*/
public interface AppUserMapper {
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
AppUser selectAppUserByUserName(String userName);
/**
* 修改用户信息
*
* @param appUser 用户信息
* @return 结果
*/
int updateAppUser(AppUser appUser);
}
目录:ruoyi-system——>src——>main——>java——>com.ruoyi.system——>mapper
注意:与 SysUserMapper 同级目录
5、创建 IAppUserService 业务层
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.AppUser;
/**
* 用户 业务层
*
* @author ruoyi
*/
public interface IAppUserService {
/**
* 通过用户账号查询用户
*
* @param userName 用户账号
* @return 用户对象信息
*/
AppUser selectAppUserByUserName(String userName);
/**
* 修改用户信息
*
* @param appUser 用户信息
* @return 结果
*/
int updateAppUser(AppUser appUser);
/**
* 密码校验
*
* @param password 明文
* @param salt 盐
* @param hashPwd 密文
* @return boolean
*/
boolean checkPassword(String password, String salt, String hashPwd);
}
目录:ruoyi-system——>src——>main——>java——>com.ruoyi.system——>service
注意:与 ISysUserService 同级目录
6、创建 AppUserServiceImpl 业务实现层
package com.ruoyi.system.service.impl;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.system.mapper.AppUserMapper;
import com.ruoyi.system.service.IAppUserService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
/**
* 用户 业务层处理
*
* @author ruoyi
*/
@Service
public class AppUserServiceImpl implements IAppUserService {
@Resource
private AppUserMapper appUserMapper;
/**
* 通过用户名查询用户
*
* @param userName 用户名
* @return 用户对象信息
*/
@Override
public AppUser selectAppUserByUserName(String userName) {
return appUserMapper.selectAppUserByUserName(userName);
}
/**
* 修改保存用户信息
*
* @param appUser 用户信息
* @return 结果
*/
@Override
public int updateAppUser(AppUser appUser) {
return appUserMapper.updateAppUser(appUser);
}
/**
* 密码校验
*
* @param password 明文
* @param salt 盐
* @param hashPwd 密文
* @return boolean
*/
public boolean checkPassword(String password, String salt, String hashPwd) {
return hashPwd.equals(DigestUtils.md5DigestAsHex(password.concat(salt).getBytes()));
}
/**
* 随即生成盐
* 8位随机数
*
* @return salt 盐
*/
private String generateSalt() {
return RandomStringUtils.randomAlphanumeric(8);
}
public static void main(String[] args) {
AppUserServiceImpl appUserService = new AppUserServiceImpl();
String password = "123456";
String salt = appUserService.generateSalt();
System.out.printf("明文密码:%s%n", password);
System.out.printf("盐:%s%n", salt);
System.out.printf("密文密码:%s%n", DigestUtils.md5DigestAsHex(password.concat(salt).getBytes()));
}
}
目录:ruoyi-system——>src——>main——>java——>com.ruoyi.system——>service——>impl
注意:与 SysUserServiceImpl 同级目录
7、创建 LoginAppUser 登录用户身份权限类
package com.ruoyi.common.core.domain.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.ruoyi.common.core.domain.entity.AppUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* 登录用户身份权限
*
* @author ruoyi
*/
public class LoginAppUser implements UserDetails {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 用户唯一标识
*/
private String token;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 登录地点
*/
private String loginLocation;
/**
* 浏览器类型
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 用户信息
*/
private AppUser appUser;
public LoginAppUser() {
}
public LoginAppUser(AppUser appUser) {
this.appUser = appUser;
}
public LoginAppUser(Long userId, AppUser appUser) {
this.userId = userId;
this.appUser = appUser;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@JSONField(serialize = false)
@Override
public String getPassword() {
return appUser.getPassword();
}
@Override
public String getUsername() {
return appUser.getUserName();
}
/**
* 账户是否未过期,过期无法验证
*/
@JSONField(serialize = false)
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*
* @return
*/
@JSONField(serialize = false)
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*
* @return
*/
@JSONField(serialize = false)
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*
* @return
*/
@JSONField(serialize = false)
@Override
public boolean isEnabled() {
return true;
}
public Long getLoginTime() {
return loginTime;
}
public void setLoginTime(Long loginTime) {
this.loginTime = loginTime;
}
public String getIpaddr() {
return ipaddr;
}
public void setIpaddr(String ipaddr) {
this.ipaddr = ipaddr;
}
public String getLoginLocation() {
return loginLocation;
}
public void setLoginLocation(String loginLocation) {
this.loginLocation = loginLocation;
}
public String getBrowser() {
return browser;
}
public void setBrowser(String browser) {
this.browser = browser;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
public Long getExpireTime() {
return expireTime;
}
public void setExpireTime(Long expireTime) {
this.expireTime = expireTime;
}
public AppUser getAppUser() {
return appUser;
}
public void setAppUser(AppUser appUser) {
this.appUser = appUser;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
}
目录:ruoyi-common——>src——>main——>java——>com.ruoyi.common——>core——>domian——>model
注意:与 LoginUser 同级目录
8、创建 LoginAppBody 用户登录对象类
package com.ruoyi.common.core.domain.model;
/**
* 用户登录对象
*
* @author ruoyi
*/
public class LoginAppBody
{
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
}
目录:ruoyi-common——>src——>main——>java——>com.ruoyi.common——>core——>domian——>model
注意:与 LoginBody 同级目录
9、通用常量信息 Constants 添加常量信息
添加:
/**
* APP令牌前缀
*/
public static final String LOGIN_APP_USER_KEY = "login_app_user_key";
/**
* APP接口前缀
*/
public static final String APP_URI = "/app/";
目录:ruoyi-common——>src——>main——>java——>com.ruoyi.common——>constant
10、创建 AppTokenService TOKEN处理类
package com.ruoyi.framework.web.service;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginAppUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import eu.bitwalker.useragentutils.UserAgent;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* token验证处理
*
* @author ruoyi
*/
@Component
public class AppTokenService {
// 令牌自定义标识
@Value("${token.header}")
private String header;
// 令牌秘钥
@Value("${token.secret}")
private String secret;
// 令牌有效期(默认30分钟)
@Value("${token.expireTime}")
private int expireTime;
protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
@Resource
private RedisCache redisCache;
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public LoginAppUser getLoginAppUser(HttpServletRequest request) {
// 获取请求携带的令牌
String token = getToken(request);
if (StringUtils.isNotEmpty(token)) {
try {
Claims claims = parseToken(token);
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_APP_USER_KEY);
String userKey = getTokenKey(uuid);
LoginAppUser loginAppUser = redisCache.getCacheObject(userKey);
return loginAppUser;
} catch (Exception e) {
}
}
return null;
}
/**
* 设置用户身份信息
*/
public void setLoginAppUser(LoginAppUser loginAppUser) {
if (StringUtils.isNotNull(loginAppUser) && StringUtils.isNotEmpty(loginAppUser.getToken())) {
refreshToken(loginAppUser);
}
}
/**
* 删除用户身份信息
*/
public void delLoginAppUser(String token) {
if (StringUtils.isNotEmpty(token)) {
String userKey = getTokenKey(token);
redisCache.deleteObject(userKey);
}
}
/**
* 创建令牌
*
* @param loginAppUser 用户信息
* @return 令牌
*/
public String createAppToken(LoginAppUser loginAppUser) {
String token = IdUtils.fastUUID();
loginAppUser.setToken(token);
setUserAgent(loginAppUser);
refreshToken(loginAppUser);
Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_APP_USER_KEY, token);
return createToken(claims);
}
/**
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
*
* @param loginAppUser
* @return 令牌
*/
public void verifyToken(LoginAppUser loginAppUser) {
long expireTime = loginAppUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshToken(loginAppUser);
}
}
/**
* 刷新令牌有效期
*
* @param loginAppUser 登录信息
*/
public void refreshToken(LoginAppUser loginAppUser) {
loginAppUser.setLoginTime(System.currentTimeMillis());
loginAppUser.setExpireTime(loginAppUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginAppUser.getToken());
redisCache.setCacheObject(userKey, loginAppUser, expireTime, TimeUnit.MINUTES);
}
/**
* 设置用户代理信息
*
* @param loginAppUser 登录信息
*/
public void setUserAgent(LoginAppUser loginAppUser) {
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = IpUtils.getIpAddr();
loginAppUser.setIpaddr(ip);
loginAppUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
loginAppUser.setBrowser(userAgent.getBrowser().getName());
loginAppUser.setOs(userAgent.getOperatingSystem().getName());
}
/**
* 从数据声明生成令牌
*
* @param claims 数据声明
* @return 令牌
*/
private String createToken(Map<String, Object> claims) {
String token = Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret).compact();
return token;
}
/**
* 从令牌中获取数据声明
*
* @param token 令牌
* @return 数据声明
*/
private Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}
/**
* 从令牌中获取用户名
*
* @param token 令牌
* @return 用户名
*/
public String getUsernameFromToken(String token) {
Claims claims = parseToken(token);
return claims.getSubject();
}
/**
* 获取请求token
*
* @param request
* @return token
*/
private String getToken(HttpServletRequest request) {
String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
token = token.replace(Constants.TOKEN_PREFIX, "");
}
return token;
}
private String getTokenKey(String uuid) {
return CacheConstants.LOGIN_APP_TOKEN_KEY + uuid;
}
}
目录:ruoyi-framework——>src——>main——>java——>com.ruoyi.framework——>web——>service
注意:与 TokenService 同级目录
11、创建 AppLoginService 登录校验方法类
package com.ruoyi.framework.web.service;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.LoginAppUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.system.service.IAppUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 登录校验方法
*
* @author ruoyi
*/
@Component
public class AppLoginService {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private AppTokenService appTokenService;
@Resource
private IAppUserService appUserSevice;
/**
* 登录验证
*
* @param username 用户名
* @param password 密码
* @return 结果
*/
public String login(String username, String password) {
AppUser appUser = appUserSevice.selectAppUserByUserName(username);
if (appUser == null) {
throw new ServiceException("用户不存在");
}
if (!appUserSevice.checkPassword(password, appUser.getSalt(), appUser.getPassword())) {
throw new ServiceException("密码不正确");
}
LoginAppUser loginAppUser = new LoginAppUser(appUser.getUserId(), appUser);
recordLoginInfo(loginAppUser.getUserId());
// 生成token
return appTokenService.createAppToken(loginAppUser);
}
/**
* 记录登录信息
*
* @param userId 用户ID
*/
private void recordLoginInfo(Long userId) {
AppUser appUser = new AppUser();
appUser.setUserId(userId);
appUser.setLoginIp(IpUtils.getIpAddr());
appUser.setLoginDate(DateUtils.getNowDate());
appUserSevice.updateAppUser(appUser);
}
}
目录:ruoyi-framework——>src——>main——>java——>com.ruoyi.framework——>web——>service
注意:与 SysLoginService 同级目录
12、修改JwtAuthenticationTokenFilter token过滤器 验证token有效性
package com.ruoyi.framework.security.filter;
import java.io.IOException;
import java.util.Collection;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginAppUser;
import com.ruoyi.framework.web.service.AppTokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
/**
* token过滤器 验证token有效性
*
* @author ruoyi
*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private TokenService tokenService;
@Resource
private AppTokenService appTokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
if (request.getRequestURI().contains(Constants.APP_URI)) {
logger.info("前台接口请求:{}", request.getRequestURI());
LoginAppUser loginAppUser = appTokenService.getLoginAppUser(request);
if (StringUtils.isNotNull(loginAppUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
appTokenService.verifyToken(loginAppUser);
auth(loginAppUser, loginAppUser.getAuthorities(), request);
}
} else {
logger.info("后台接口请求:{}", request.getRequestURI());
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
tokenService.verifyToken(loginUser);
auth(loginUser, loginUser.getAuthorities(), request);
}
}
chain.doFilter(request, response);
}
/**
* 验证token
*
* @param obj 登录信息
* @param authorities 已授予的权限集合
* @param request 网络请求
*/
private void auth(Object obj, Collection<? extends GrantedAuthority> authorities, HttpServletRequest request) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(obj, null, authorities);
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
目录:ruoyi-framework——>src——>main——>java——>com.ruoyi.framework——>security——>filter
13、安全服务工具类 SecurityUtils 添加信息
添加:
/**
* 获取APP用户
**/
public static LoginAppUser getLoginAppUser()
{
try
{
return (LoginAppUser) getAuthentication().getPrincipal();
}
catch (Exception e)
{
throw new ServiceException("获取APP用户信息异常", HttpStatus.UNAUTHORIZED);
}
}
目录:ruoyi-common——>src——>main——>java——>com.ruoyi.common——>utils
14、web层通用数据类 BaseController 添加信息
添加:
/**
* 获取APP用户缓存信息
*/
public LoginAppUser getLoginAppUser()
{
return SecurityUtils.getLoginAppUser();
}
目录:ruoyi-common——>src——>main——>java——>com.ruoyi.common——>core——>controller
15、创建 AppLoginController 控制器
package com.ruoyi.web.controller.system;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.LoginAppBody;
import com.ruoyi.framework.web.service.AppLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 登录验证
*
* @author ruoyi
*/
@Api("APP登录管理")
@RestController
@RequestMapping("/app")
public class AppLoginController extends BaseController {
@Resource
private AppLoginService appLoginService;
@ApiOperation("登录")
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginAppBody loginAppBody) {
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = appLoginService.login(loginAppBody.getUsername(), loginAppBody.getPassword());
ajax.put(Constants.TOKEN, token);
return ajax;
}
@ApiOperation("根据token获取用户信息")
@GetMapping("/userInfo")
public AjaxResult userInfo() {
AppUser appUser = getLoginAppUser().getAppUser();
AjaxResult ajax = AjaxResult.success();
ajax.put("appUser", appUser);
return ajax;
}
}
目录:ruoyi-admin——>src——>main——>java——>com.ruoyi——>web——>controller——>system
注意:与 SysUserController 同级目录
16、SecurityConfig添加匿名访问地址
添加:
// 对于APP登录login 允许匿名访问
.antMatchers("/app/login").permitAll()
目录:ruoyi-framework——>src——>main——>java——>com.ruoyi.framework——>config
17、启动服务测试接口
文章来源:https://www.toymoban.com/news/detail-762317.html
文章来源地址https://www.toymoban.com/news/detail-762317.html
到了这里,关于若依@v3.8.6前后端分离版:添加新用户表添加新登录接口,用于小程序或者APP获取token,并使用若依的验证方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!