完成springboot-jwt升级重构
This commit is contained in:
parent
7b5e72ab34
commit
1e578567b0
@ -1,3 +1,9 @@
|
||||
# Table of Contents
|
||||
|
||||
* [简介](#简介)
|
||||
* [测试](#测试)
|
||||
* [许可证](#许可证)
|
||||
|
||||
|
||||
## 简介
|
||||
|
||||
@ -30,12 +36,21 @@ Content-Type: application/json
|
||||
``` json
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "12345678",
|
||||
"appid": "111",
|
||||
"imei": "imei"
|
||||
"password": "12345678"
|
||||
}
|
||||
```
|
||||
|
||||
可使用postman或者curl方式,本人更愿意使用curl方式:
|
||||
|
||||
```
|
||||
curl -X POST http://localhost:9095/login -H 'Content-Type: application/json' -d '
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "12345678"
|
||||
}
|
||||
'
|
||||
```
|
||||
|
||||
返回值:
|
||||
|
||||
``` json
|
||||
@ -63,6 +78,12 @@ Content-Type: application/json
|
||||
Authorization: "上面拿到的token值"
|
||||
```
|
||||
|
||||
curl访问语法:
|
||||
|
||||
```
|
||||
curl -X GET http://localhost:9095/api/v1/join?imei=imei -H 'Content-Type: application/json' -H 'Authorization: 上面拿到的token值'
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
Copyright (c) 2018 Xiong Neng
|
||||
|
@ -42,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -85,6 +85,7 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.7</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -3,14 +3,12 @@ package com.xncoding.jwt.api;
|
||||
import com.xncoding.jwt.api.model.BaseResponse;
|
||||
import com.xncoding.jwt.api.model.LoginParam;
|
||||
import com.xncoding.jwt.common.util.JWTUtil;
|
||||
import com.xncoding.jwt.dao.entity.ManagerInfo;
|
||||
import com.xncoding.jwt.model.ManagerInfo;
|
||||
import com.xncoding.jwt.service.ManagerInfoService;
|
||||
import com.xncoding.jwt.shiro.ShiroKit;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -32,41 +30,16 @@ public class LoginController {
|
||||
_logger.info("用户请求登录获取Token");
|
||||
String username = loginParam.getUsername();
|
||||
String password = loginParam.getPassword();
|
||||
String appid = loginParam.getAppid();
|
||||
String imei = loginParam.getImei();
|
||||
ManagerInfo user = managerInfoService.findByUsername(username);
|
||||
//盐(用户名+随机数)
|
||||
//随机数盐
|
||||
String salt = user.getSalt();
|
||||
//原密码
|
||||
//原密码加密(通过username + salt作为盐)
|
||||
String encodedPassword = ShiroKit.md5(password, username + salt);
|
||||
if (user.getPassword().equals(encodedPassword)) {
|
||||
if (StringUtils.isNotEmpty(appid) && StringUtils.isNotEmpty(imei)) {
|
||||
return new BaseResponse<>(true, "Login success", JWTUtil.signSocket(username, encodedPassword, appid, imei));
|
||||
}
|
||||
return new BaseResponse<>(true, "Login success", JWTUtil.sign(username, encodedPassword));
|
||||
} else {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/notifyLogin")
|
||||
public BaseResponse<String> notifyLogin(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
|
||||
@RequestBody LoginParam loginParam) {
|
||||
_logger.info("登录用户推送请求登录获取Token");
|
||||
String username = loginParam.getUsername();
|
||||
String password = loginParam.getPassword();
|
||||
ManagerInfo user = managerInfoService.findByUsername(username);
|
||||
if (user.getPassword().equals(password)) {
|
||||
return new BaseResponse<>(true, "Login success", JWTUtil.sign(username, password));
|
||||
} else {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(path = "/401")
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
public BaseResponse unauthorized() {
|
||||
return new BaseResponse<>(false, "Unauthorized", null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ public class PublicController {
|
||||
*/
|
||||
@RequestMapping(value = "/join", method = RequestMethod.GET)
|
||||
@RequiresAuthentication
|
||||
public BaseResponse join(@RequestHeader("Authorization") String token,
|
||||
@RequestParam("imei") String imei) {
|
||||
public BaseResponse join(@RequestParam("imei") String imei) {
|
||||
_logger.info("入网查询接口 start... imei=" + imei);
|
||||
BaseResponse result = new BaseResponse();
|
||||
result.setSuccess(true);
|
||||
|
@ -16,14 +16,6 @@ public class LoginParam {
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* Application ID
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* IMEI码
|
||||
*/
|
||||
private String imei;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
@ -40,20 +32,4 @@ public class LoginParam {
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getImei() {
|
||||
return imei;
|
||||
}
|
||||
|
||||
public void setImei(String imei) {
|
||||
this.imei = imei;
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package com.xncoding.jwt.common.constant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 常量列表
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/01/07
|
||||
*/
|
||||
public class ConstantsList {
|
||||
// 应收款项列表
|
||||
public static final List<String> INCOME_TYPE_LIST = new ArrayList<String>() {{
|
||||
add("租金");
|
||||
add("市场管理费");
|
||||
add("物业管理费");
|
||||
add("其他");
|
||||
}};
|
||||
|
||||
// 市场列表
|
||||
public static final List<String> MARKET_LIST = new ArrayList<String>() {{
|
||||
add("一期市场");
|
||||
add("二期市场");
|
||||
add("三期市场");
|
||||
}};
|
||||
|
||||
// 业态
|
||||
public static final List<String> BUSINESS_LIST = new ArrayList<String>() {{
|
||||
add("男装");
|
||||
add("女装");
|
||||
add("玩具");
|
||||
add("餐饮");
|
||||
add("家具");
|
||||
}};
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.xncoding.jwt.common.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* 表常量字典
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/01/07
|
||||
*/
|
||||
public class DictMap {
|
||||
/**
|
||||
* 后台管理用户表 - 状态(1:正常 2:禁用)
|
||||
*/
|
||||
public static final String KEY_USER_STATUS = "t_manager.status";
|
||||
/**
|
||||
* POS机表 - 机具状态(1:正常 2:故障 3:维修中(返厂) 4:已禁用(丢失) 5:已停用(回收))
|
||||
*/
|
||||
public static final String KEY_POS_POS_STATUS = "t_pos.pos_state";
|
||||
/**
|
||||
* POS机监控表 - 在线状态(1:在线 2:离线)
|
||||
*/
|
||||
public static final String KEY_POS_MONITOR_STATUS = "t_pos_monitor.online_state";
|
||||
/**
|
||||
* APP表 - 发布范围(1:全网发布 2:灰度发布)
|
||||
*/
|
||||
public static final String KEY_APP_PUBLISH_RANGE = "t_app.publish_range";
|
||||
|
||||
/**
|
||||
* 内部用,ClassName + FieldName为key
|
||||
*/
|
||||
private static final Map<String, TreeMap<Integer, String>> _imap = new HashMap<>();
|
||||
|
||||
static {
|
||||
_imap.put(KEY_USER_STATUS, new TreeMap<Integer, String>() {{
|
||||
put(1, "正常");
|
||||
put(2, "禁用");
|
||||
}});
|
||||
_imap.put(KEY_POS_POS_STATUS, new TreeMap<Integer, String>() {{
|
||||
put(1, "正常");
|
||||
put(2, "故障");
|
||||
put(3, "维修中(返厂)");
|
||||
put(4, "已禁用(丢失)");
|
||||
put(5, "已停用(回收)");
|
||||
}});
|
||||
_imap.put(KEY_POS_MONITOR_STATUS, new TreeMap<Integer, String>() {{
|
||||
put(1, "在线");
|
||||
put(2, "离线");
|
||||
}});
|
||||
_imap.put(KEY_APP_PUBLISH_RANGE, new TreeMap<Integer, String>() {{
|
||||
put(1, "全网发布");
|
||||
put(2, "灰度发布");
|
||||
}});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型key获取某个字典Map
|
||||
*
|
||||
* @param type 常量类型
|
||||
* @return 字典Map
|
||||
*/
|
||||
public static TreeMap<Integer, String> map(String type) {
|
||||
return _imap.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和数字获取对应的字符串
|
||||
*
|
||||
* @param type 字典类型
|
||||
* @param key 数字
|
||||
* @return 对应的字符串
|
||||
*/
|
||||
public static String value(String type, Integer key) {
|
||||
return key != null ? map(type).get(key) : null;
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.xncoding.jwt.common.util;
|
||||
|
||||
/**
|
||||
* 常用工具类,字符串、数字相关
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/1/15
|
||||
*/
|
||||
public class CommonUtil {
|
||||
/**
|
||||
* 检查某版本是否比现在版本更大些
|
||||
*
|
||||
* @param version 某版本
|
||||
* @param nowVersion 现在使用的版本
|
||||
* @return 是否版本数更大
|
||||
*/
|
||||
public static boolean isNewer(String version, String nowVersion) {
|
||||
try {
|
||||
String[] versions = version.split("\\.");
|
||||
String[] nowVersions = nowVersion.split("\\.");
|
||||
|
||||
if (versions.length != nowVersions.length) {
|
||||
return false;
|
||||
}
|
||||
int sum = 0;
|
||||
for (String v : versions) {
|
||||
sum += sum * 10 + Integer.valueOf(v);
|
||||
}
|
||||
|
||||
int nowSum = 0;
|
||||
for (String nv : nowVersions) {
|
||||
nowSum += nowSum * 10 + Integer.valueOf(nv);
|
||||
}
|
||||
|
||||
return sum > nowSum;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,296 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.xncoding.jwt.common.util;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateUtil {
|
||||
private final static SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
|
||||
|
||||
private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
private final static SimpleDateFormat sdfDays = new SimpleDateFormat("yyyyMMdd");
|
||||
|
||||
private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private final static SimpleDateFormat sdfmsTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
|
||||
private final static SimpleDateFormat allTime = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
|
||||
private final static SimpleDateFormat sdfDay_ = new SimpleDateFormat("yyyy/MM/dd");
|
||||
|
||||
|
||||
/**
|
||||
* 获取YYYY格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getYear() {
|
||||
return sdfYear.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getYear(Date date) {
|
||||
return sdfYear.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDay() {
|
||||
return sdfDay.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDay(Date date) {
|
||||
return sdfDay.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYYMMDD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDays() {
|
||||
return sdfDays.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYYMMDD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDays(Date date) {
|
||||
return sdfDays.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY/MM/DD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDays_(Date date) {
|
||||
return sdfDay_.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD HH:mm:ss格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getTime() {
|
||||
return sdfTime.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD HH:mm:ss.SSS格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getMsTime() {
|
||||
return sdfmsTime.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYYMMDDHHmmss格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getAllTime() {
|
||||
return allTime.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD HH:mm:ss格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getTime(Date date) {
|
||||
return sdfTime.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s
|
||||
* @param e
|
||||
* @return boolean
|
||||
* @throws
|
||||
* @Title: compareDate
|
||||
* @Description:(日期比较,如果s>=e 返回true 否则返回false)
|
||||
* @author luguosui
|
||||
*/
|
||||
public static boolean compareDate(String s, String e) {
|
||||
if (parseDate(s) == null || parseDate(e) == null) {
|
||||
return false;
|
||||
}
|
||||
return parseDate(s).getTime() >= parseDate(e).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Date parseDate(String date) {
|
||||
try {
|
||||
return sdfDay.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Date parseTime(String date) {
|
||||
try {
|
||||
return sdfTime.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Date parse(String date, String pattern) {
|
||||
DateFormat fmt = new SimpleDateFormat(pattern);
|
||||
try {
|
||||
return fmt.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String format(Date date, String pattern) {
|
||||
DateFormat fmt = new SimpleDateFormat(pattern);
|
||||
return fmt.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把日期转换为Timestamp
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Timestamp format(Date date) {
|
||||
return new Timestamp(date.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验日期是否合法
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidDate(String s) {
|
||||
try {
|
||||
sdfTime.parse(s);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验日期是否合法
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidDate(String s, String pattern) {
|
||||
DateFormat fmt = new SimpleDateFormat(pattern);
|
||||
try {
|
||||
fmt.parse(s);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期偏移指定时间后的时间
|
||||
*
|
||||
* @param date 基准日期
|
||||
* @param calendarField 偏移的粒度大小(小时、天、月等)使用Calendar中的常数
|
||||
* @param offsite 偏移量,正数为向后偏移,负数为向前偏移
|
||||
* @return 偏移后的日期
|
||||
*/
|
||||
public static Date offsiteDate(Date date, int calendarField, int offsite) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(calendarField, offsite);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回日期零时
|
||||
*
|
||||
* @param date 目标日期
|
||||
* @return 目标日期零时
|
||||
*/
|
||||
public static Date getDateStartTime(Date date) {
|
||||
String str = format(date, "yyyyMMdd") + "000000";
|
||||
try {
|
||||
return allTime.parse(str);
|
||||
} catch (ParseException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回日期最后时间End
|
||||
*
|
||||
* @param date 目标日期
|
||||
* @return 目标日日期最后时间
|
||||
*/
|
||||
public static Date getDateEndTime(Date date) {
|
||||
String str = format(date, "yyyyMMdd") + "235959";
|
||||
try {
|
||||
return allTime.parse(str);
|
||||
} catch (ParseException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,12 +3,10 @@ package com.xncoding.jwt.common.util;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
|
||||
public class JWTUtil {
|
||||
@ -18,6 +16,23 @@ public class JWTUtil {
|
||||
// 过期时间5分钟
|
||||
private static final long EXPIRE_TIME = 5 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* 生成签名,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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验token是否正确
|
||||
*
|
||||
@ -26,17 +41,12 @@ public class JWTUtil {
|
||||
* @return 是否正确
|
||||
*/
|
||||
public static boolean verify(String token, String username, String secret) {
|
||||
try {
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withClaim("username", username)
|
||||
.build();
|
||||
DecodedJWT jwt = verifier.verify(token);
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
log.error("校验token失败", exception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,129 +55,8 @@ public class JWTUtil {
|
||||
* @return token中包含的用户名
|
||||
*/
|
||||
public static String getUsername(String token) {
|
||||
try {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim("username").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名,5min后过期
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param secret 用户的密码
|
||||
* @return 加密的token
|
||||
*/
|
||||
public static String sign(String username, String secret) {
|
||||
try {
|
||||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create()
|
||||
.withClaim("username", username)
|
||||
.withExpiresAt(date)
|
||||
.sign(algorithm);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------以下是socket校验--------------------------*/
|
||||
/**
|
||||
* 生成Socket Token签名, 5min后过期
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param secret 用户的密码
|
||||
* @param appid applicationId
|
||||
* @param imei IMEI码
|
||||
* @return 加密的token
|
||||
*/
|
||||
public static String signSocket(String username, String secret, String appid, String imei) {
|
||||
try {
|
||||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create()
|
||||
.withClaim("username", username)
|
||||
.withClaim("appid", appid)
|
||||
.withClaim("imei", imei)
|
||||
.withExpiresAt(date)
|
||||
.sign(algorithm);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验token是否正确
|
||||
*
|
||||
* @param token 密钥
|
||||
* @param secret 用户的密码
|
||||
* @return 是否正确
|
||||
*/
|
||||
public static boolean verifySocket(String token, String secret) {
|
||||
try {
|
||||
DecodedJWT jwt1 = JWT.decode(token);
|
||||
String username = jwt1.getClaim("username").asString();
|
||||
String appid = jwt1.getClaim("appid").asString();
|
||||
String imei = jwt1.getClaim("imei").asString();
|
||||
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withClaim("username", username)
|
||||
.withClaim("appid", appid)
|
||||
.withClaim("imei", imei)
|
||||
.build();
|
||||
DecodedJWT jwt = verifier.verify(token);
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
log.error("校验token失败", exception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得token中的信息无需secret解密也能获得
|
||||
*
|
||||
* @return token中包含的用户名
|
||||
*/
|
||||
public static String getSocketUsername(String token) {
|
||||
try {
|
||||
DecodedJWT jwt1 = JWT.decode(token);
|
||||
return jwt1.getClaim("username").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得token中的信息无需secret解密也能获得
|
||||
*
|
||||
* @return token中包含的Appid
|
||||
*/
|
||||
public static String getSocketAppid(String token) {
|
||||
try {
|
||||
DecodedJWT jwt1 = JWT.decode(token);
|
||||
return jwt1.getClaim("appid").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得token中的信息无需secret解密也能获得
|
||||
*
|
||||
* @return token中包含的IMEI码
|
||||
*/
|
||||
public static String getSocketImei(String token) {
|
||||
try {
|
||||
DecodedJWT jwt1 = JWT.decode(token);
|
||||
return jwt1.getClaim("imei").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.xncoding.jwt.common.dao.entity;
|
||||
package com.xncoding.jwt.dao.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
@ -1,4 +1,4 @@
|
||||
package com.xncoding.jwt.common.dao.entity;
|
||||
package com.xncoding.jwt.dao.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
@ -1,4 +1,4 @@
|
||||
package com.xncoding.jwt.common.dao.entity;
|
||||
package com.xncoding.jwt.dao.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
@ -1,4 +1,4 @@
|
||||
package com.xncoding.jwt.common.dao.entity;
|
||||
package com.xncoding.jwt.dao.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
@ -1,4 +1,4 @@
|
||||
package com.xncoding.jwt.common.dao.entity;
|
||||
package com.xncoding.jwt.dao.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
@ -1,11 +1,9 @@
|
||||
package com.xncoding.jwt.dao.entity;
|
||||
package com.xncoding.jwt.model;
|
||||
|
||||
import com.xncoding.jwt.common.constant.DictMap;
|
||||
import com.xncoding.jwt.common.dao.entity.Manager;
|
||||
import com.xncoding.jwt.dao.domain.Manager;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description: 后台运维管理员信息
|
||||
@ -91,7 +89,4 @@ public class ManagerInfo extends Manager implements Serializable {
|
||||
this.pnames = pnames;
|
||||
}
|
||||
|
||||
public void buildTable() {
|
||||
stateStr = DictMap.value(DictMap.KEY_USER_STATUS, getState());
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.xncoding.jwt.dao.entity;
|
||||
package com.xncoding.jwt.model;
|
||||
|
||||
import com.xncoding.jwt.common.dao.entity.Permission;
|
||||
import com.xncoding.jwt.common.dao.entity.Role;
|
||||
import com.xncoding.jwt.dao.domain.Permission;
|
||||
import com.xncoding.jwt.dao.domain.Role;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
@ -1,7 +1,8 @@
|
||||
package com.xncoding.jwt.service;
|
||||
|
||||
import com.xncoding.jwt.dao.entity.ManagerInfo;
|
||||
import com.xncoding.jwt.dao.entity.SysRole;
|
||||
import com.xncoding.jwt.model.ManagerInfo;
|
||||
import com.xncoding.jwt.model.SysRole;
|
||||
import com.xncoding.jwt.shiro.ShiroKit;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -18,20 +19,23 @@ public class ManagerInfoService {
|
||||
|
||||
/**
|
||||
* 通过名称查找用户
|
||||
* 这里我直接写常量,实际生产环境会通过DAO访问数据库
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public ManagerInfo findByUsername(String username) {
|
||||
ManagerInfo managerInfo = new ManagerInfo();
|
||||
managerInfo.setUsername(username);
|
||||
managerInfo.setPids("1,2,3");
|
||||
managerInfo.setPidsList(Arrays.asList(1, 2, 3));
|
||||
managerInfo.setPnames("第1个,第2个");
|
||||
managerInfo.setState(1);
|
||||
managerInfo.setCreatedTime(new Date());
|
||||
managerInfo.setName("系统管理员");
|
||||
managerInfo.setPassword("4a496ba2a4172c71540fa643ddc8bb7c");
|
||||
managerInfo.setSalt("b4752b4b73034de06afb2db30fe19061");
|
||||
// 随机数
|
||||
managerInfo.setSalt("ef748186673033723bbf4e056f4ec92e");
|
||||
managerInfo.setPassword("da9c3061ae5c0973a3d48e4e721cfbad");
|
||||
List<SysRole> roles = new ArrayList<>();
|
||||
SysRole role = new SysRole();
|
||||
role.setId(1);
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.xncoding.jwt.shiro;
|
||||
|
||||
import com.xncoding.jwt.common.dao.entity.Permission;
|
||||
import com.xncoding.jwt.dao.domain.Permission;
|
||||
import com.xncoding.jwt.common.util.JWTUtil;
|
||||
import com.xncoding.jwt.dao.entity.ManagerInfo;
|
||||
import com.xncoding.jwt.dao.entity.SysRole;
|
||||
import com.xncoding.jwt.model.ManagerInfo;
|
||||
import com.xncoding.jwt.model.SysRole;
|
||||
import com.xncoding.jwt.service.ManagerInfoService;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
|
@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.xncoding.jwt.shiro;
|
||||
|
||||
import com.xncoding.jwt.dao.entity.ManagerInfo;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
/**
|
||||
|
@ -27,20 +27,5 @@ logging:
|
||||
ROOT: INFO
|
||||
com:
|
||||
xncoding: DEBUG
|
||||
file: E:/logs/pos-api.log
|
||||
file: D:/logs/pos-api.log
|
||||
|
||||
---
|
||||
|
||||
#####################################################################
|
||||
######################## 测试环境profile ##########################
|
||||
#####################################################################
|
||||
|
||||
spring:
|
||||
profiles: test
|
||||
|
||||
logging:
|
||||
level:
|
||||
ROOT: INFO
|
||||
com:
|
||||
xncoding: DEBUG
|
||||
file: /var/logs/pos-api.log
|
||||
|
@ -1,15 +0,0 @@
|
||||
package com.xncoding.jwt;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* 测试密码加密
|
||||
*/
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class ApplicationTests {
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.xncoding.jwt;
|
||||
|
||||
import com.xncoding.jwt.common.util.JWTUtil;
|
||||
import com.xncoding.jwt.shiro.ShiroKit;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -12,14 +13,20 @@ import org.junit.Test;
|
||||
*/
|
||||
public class SimpleTest {
|
||||
@Test
|
||||
public void testMd5() {
|
||||
//盐(用户名+随机数)
|
||||
public void testJwt() {
|
||||
String username = "admin";
|
||||
//随机数
|
||||
String salt = ShiroKit.getRandomSalt(16);
|
||||
//原密码
|
||||
String password = "12345678";
|
||||
String encodedPassword = ShiroKit.md5(password, username + salt);
|
||||
System.out.println("这个是保存进数据库的密码:" + encodedPassword);
|
||||
System.out.println("这个是保存进数据库的盐:" + salt);
|
||||
System.out.println("这个是保存进数据库的随机数:" + salt);
|
||||
System.out.println("这个是保存进数据库的加密后密码:" + encodedPassword);
|
||||
// 生成token
|
||||
String token = JWTUtil.sign(username, encodedPassword);
|
||||
System.out.println("token=" + token);
|
||||
// 验证token
|
||||
JWTUtil.verify(token, username, encodedPassword);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package com.xncoding.jwt.common.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class CommonUtilTest {
|
||||
|
||||
@Test
|
||||
public void isNewer() {
|
||||
assertThat(CommonUtil.isNewer("1.2.1", "1.2.0"), is(true));
|
||||
assertThat(CommonUtil.isNewer("1.2", "1.2.0"), is(false));
|
||||
assertThat(CommonUtil.isNewer("2.1.9", "1.2.0"), is(true));
|
||||
assertThat(CommonUtil.isNewer("adfa.1.3", "1.2.0"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimestamp() {
|
||||
// 1516072088813
|
||||
// 1441594722
|
||||
System.out.println(System.currentTimeMillis());
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user