目录
1、登录接口方法login(),其中用到密码工具类PasswordUtils和生成Token的userInfo()方法。
1.3 userInfo():其中包含JwtUtil工具类的sign()方法和RedisUtil工具类的set()和expire()
1.3.2 set()和expire():设置Token换成有效时间方法set()和Redis设置过期时间方法expire()
1、登录接口方法login(),其中用到密码工具类PasswordUtils和生成Token的userInfo()方法。
1.1 login():
/**
* 登录接口,获取用户名和密码,返回Token
*/
@ApiOperation(value = "APP登录接口", notes = "APP登录接口")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result<JSONObject> login(@RequestBody LoginModel loginModel) {
Result<JSONObject> result;
// 获取用户输入的账号和密码
String username = loginModel.getUsername();
String password = loginModel.getPassword();
// 1.根据用户输入的内容创建查询条件
LambdaQueryWrapper<AppUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AppUser::getUsername, username);
// 2.获取到根据账号查询到的数据
AppUser appUser = appUserService.getOne(queryWrapper);
// 3.检测用户是否有效
result = appUserService.checkUserIsEffective(appUser);
if (!result.isSuccess()) {
return result;
}
// 4. 这是数据库中的密码(加密后的密码)
String sysPassword = appUser.getPassword();
if (!sysPassword.equals(PasswordUtils.encrypt(password))) {
result.error500("用户名或密码错误");
return result;
}
// 根据用户名查询其对应的角色信息
QueryWrapper<AppUserRole> roleWrapper = new QueryWrapper<>();
roleWrapper.eq("user_id", appUser.getId());
// 获取到用户对应的角色信息
AppUserRole userRole = roleService.getOne(roleWrapper);
// 5.生成Token、在Result中添加信息并返回给前端
userInfo(appUser, result, userRole);
return result;
}
1.2 PasswordUtils密码工具类:
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
public class PasswordUtils {
/**加密key*/
private static String key = "JEECGBOOT1423670";
/**
* 加密:明文密码 -----> 密文密码
* @param password 明文
*/
public static String encrypt(String password) {
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes());
return aes.encryptHex(password);
}
/**
* 解密:密文密码 -----> 明文密码
* @param encryptString 加密后的密文
*/
public static String decrypt(String encryptString){
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes());
// 解密为字符串
return aes.decryptStr(encryptString, CharsetUtil.CHARSET_UTF_8);
}
public static void main(String[] args) {
String password = "123456";
String encrypt = encrypt(password);
System.out.println("加密后:" + encrypt);
String decrypt = decrypt("88a8a83f8e4402d3317d7acc99e5d835");
System.out.println("解密后:" + decrypt);
}
}
1.3 userInfo():其中包含JwtUtil工具类的sign()方法和RedisUtil工具类的set()和expire()
/**
* 生成Token并返回用户信息
*
* @param appUser 用户
* @param result 结果
*/
private void userInfo(AppUser appUser, Result<JSONObject> result, AppUserRole userRole) {
// 获取到用户名和密码
String appPassword = appUser.getPassword();
String username = appUser.getUsername();
JSONObject obj = new JSONObject();
// 生成Token
String token = JwtUtil.sign(username, appPassword);
// 设置Token缓存有效时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
// Redis设置过期时间为30天(以秒为单位)
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
// 添加信息并返回
obj.put("token", token);
obj.put("userInfo", appUser);
obj.put("roleInfo", userRole);
result.setResult(obj);
result.success("登录成功");
}
1.3.1 sign():生成加密Token
/**
* 生成签名,5min后过期
*
* @param username 用户名
* @param secret 用户的密码
* @return 加密的token
*/
public static String sign(String username, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带username信息
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
}
1.3.2 set()和expire():设置Token换成有效时间方法set()和Redis设置过期时间方法expire()
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
2、Result:定义接口返回数据格式Result类
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.jeecg.common.constant.CommonConstant;
import lombok.Data;
/**
* 接口返回数据格式
*/
@Data
@ApiModel(value="接口返回对象", description="接口返回对象")
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
@ApiModelProperty(value = "成功标志")
private boolean success = true;
/**
* 返回处理消息
*/
@ApiModelProperty(value = "返回处理消息")
private String message = "操作成功!";
/**
* 返回代码
*/
@ApiModelProperty(value = "返回代码")
private Integer code = 0;
/**
* 返回数据对象 data
*/
@ApiModelProperty(value = "返回数据对象")
private T result;
/**
* 时间戳
*/
@ApiModelProperty(value = "时间戳")
private long timestamp = System.currentTimeMillis();
public Result() {
}
public Result<T> success(String message) {
this.message = message;
this.code = CommonConstant.SC_OK_200;
this.success = true;
return this;
}
@Deprecated
public static Result<Object> ok() {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage("成功");
return r;
}
@Deprecated
public static Result<Object> ok(String msg) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
return r;
}
@Deprecated
public static Result<Object> ok(Object data) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static<T> Result<T> OK() {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage("成功");
return r;
}
public static<T> Result<T> OK(T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static<T> Result<T> OK(String msg, T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
r.setResult(data);
return r;
}
public static Result<Object> error(String msg) {
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
}
public static Result<Object> error(int code, String msg) {
Result<Object> r = new Result<Object>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
}
public Result<T> error500(String message) {
this.message = message;
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
this.success = false;
return this;
}
/**
* 无权限访问返回结果
*/
public static Result<Object> noauth(String msg) {
return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg);
}
@JsonIgnore
private String onlTable;
}