11 changed files with 556 additions and 0 deletions
@ -0,0 +1,120 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
|
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<parent> |
||||
|
<artifactId>epdc-commons</artifactId> |
||||
|
<groupId>com.esua.epdc</groupId> |
||||
|
<version>1.0.0</version> |
||||
|
</parent> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>epdc-common-clienttoken</artifactId> |
||||
|
<packaging>jar</packaging> |
||||
|
|
||||
|
<name>epdc-common-clienttoken</name> |
||||
|
<url>http://www.example.com</url> |
||||
|
<description>客户端token</description> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>com.esua.epdc</groupId> |
||||
|
<artifactId>epdc-commons-tools</artifactId> |
||||
|
<version>${project.version}</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-aop</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-configuration-processor</artifactId> |
||||
|
<optional>true</optional> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<groupId>com.vaadin.external.google</groupId> |
||||
|
<artifactId>android-json</artifactId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-autoconfigure</artifactId> |
||||
|
<scope>compile</scope> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-autoconfigure-processor</artifactId> |
||||
|
<scope>compile</scope> |
||||
|
<optional>true</optional> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-log4j2</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
<build> |
||||
|
<finalName>${project.artifactId}</finalName> |
||||
|
|
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<artifactId>maven-clean-plugin</artifactId> |
||||
|
</plugin> |
||||
|
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> |
||||
|
<plugin> |
||||
|
<artifactId>maven-resources-plugin</artifactId> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||
|
<configuration> |
||||
|
<parameters>true</parameters> |
||||
|
<source>${maven.compiler.source}</source> <!-- 源代码使用的开发版本 --> |
||||
|
<target>${maven.compiler.target}</target> <!-- 需要生成的目标class文件的编译版本 --> |
||||
|
<encoding>${project.build.sourceEncoding}</encoding> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<artifactId>maven-surefire-plugin</artifactId> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<artifactId>maven-war-plugin</artifactId> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<artifactId>maven-install-plugin</artifactId> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<artifactId>maven-deploy-plugin</artifactId> |
||||
|
</plugin> |
||||
|
|
||||
|
<!-- jar插件 --> |
||||
|
<plugin> |
||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||
|
<artifactId>maven-jar-plugin</artifactId> |
||||
|
<version>2.4</version> |
||||
|
<configuration> |
||||
|
<archive> |
||||
|
<manifest> |
||||
|
<addDefaultImplementationEntries>true</addDefaultImplementationEntries> |
||||
|
</manifest> |
||||
|
</archive> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
|
||||
|
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> |
||||
|
</build> |
||||
|
</project> |
@ -0,0 +1,31 @@ |
|||||
|
/** |
||||
|
* Copyright 2018 人人开源 http://www.renren.io
|
||||
|
* <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.elink.esua.common.token.annotation; |
||||
|
|
||||
|
import java.lang.annotation.*; |
||||
|
|
||||
|
/** |
||||
|
* 登录效验 |
||||
|
* @author chenshun |
||||
|
* @email sunlightcs@gmail.com |
||||
|
* @date 2017/9/23 14:30 |
||||
|
*/ |
||||
|
@Target(ElementType.METHOD) |
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
@Documented |
||||
|
public @interface Login { |
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
/** |
||||
|
* Copyright 2018 人人开源 http://www.renren.io
|
||||
|
* <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.elink.esua.common.token.annotation; |
||||
|
|
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
/** |
||||
|
* 登录用户信息 |
||||
|
* |
||||
|
* @author chenshun |
||||
|
* @email sunlightcs@gmail.com |
||||
|
* @date 2017-03-23 20:39 |
||||
|
*/ |
||||
|
@Target(ElementType.PARAMETER) |
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
public @interface LoginUser { |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package com.elink.esua.common.token.annotation; |
||||
|
|
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
@Retention(RetentionPolicy.CLASS)//生命注释保留时长,这里无需反射使用,使用CLASS级别
|
||||
|
@Target(ElementType.METHOD)//生命可以使用此注解的元素级别类型(如类、方法变量等)
|
||||
|
public @interface NeedClientToken { |
||||
|
|
||||
|
boolean value() default true; |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
package com.elink.esua.common.token.dto; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 用户token |
||||
|
* |
||||
|
* @author rongchao |
||||
|
* @Date 18-10-31 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class TokenDto implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 用户信息 |
||||
|
*/ |
||||
|
private UserTokenDto userInfoDto; |
||||
|
|
||||
|
/** |
||||
|
* 令牌 |
||||
|
*/ |
||||
|
private String token; |
||||
|
|
||||
|
/** |
||||
|
* 过期时间 |
||||
|
*/ |
||||
|
private Date expireTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
private Date updateTime; |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
package com.elink.esua.common.token.dto; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* 用户信息DTO |
||||
|
* |
||||
|
* @author rongchao |
||||
|
* @Date 18-12-1 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class UserTokenDto { |
||||
|
|
||||
|
/** |
||||
|
* 用户ID |
||||
|
*/ |
||||
|
private String userId; |
||||
|
|
||||
|
/** |
||||
|
* 昵称 |
||||
|
*/ |
||||
|
private String nickName; |
||||
|
|
||||
|
/** |
||||
|
* 用户头像 |
||||
|
*/ |
||||
|
private String faceImg; |
||||
|
|
||||
|
/** |
||||
|
* 手机号 |
||||
|
*/ |
||||
|
private String mobile; |
||||
|
|
||||
|
/** |
||||
|
* 真是姓名 |
||||
|
*/ |
||||
|
private String realName; |
||||
|
|
||||
|
/** |
||||
|
* 网格ID |
||||
|
*/ |
||||
|
private String gridId; |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
package com.elink.esua.common.token.enums; |
||||
|
|
||||
|
import com.elink.esua.common.token.error.IErrorCode; |
||||
|
|
||||
|
/** |
||||
|
* client token错误码 |
||||
|
* |
||||
|
* @author rongchao |
||||
|
* @Date 18-11-24 |
||||
|
*/ |
||||
|
public enum ErrorCode implements IErrorCode { |
||||
|
|
||||
|
SUCCESS(0, "请求成功"), |
||||
|
|
||||
|
ERR10001(10001, "clientToken不合法或者已过期"), |
||||
|
ERR10002(10002, "无法获取当前用户的信息,无法生成clientToken。"), |
||||
|
ERR10003(10003, "clientToken生成失败,请重试。"), |
||||
|
ERR10004(10004, "返回的Object类型不是EsuaResponse,无法添加token!"), |
||||
|
ERR10005(10005, "clentToken不能为空"), |
||||
|
|
||||
|
ERR500(500, "Internal Server Error"), |
||||
|
ERR501(501, "参数绑定异常"), |
||||
|
|
||||
|
ERR(ErrorCode.COMMON_ERR_CODE, "其他异常"); |
||||
|
|
||||
|
private int code; |
||||
|
|
||||
|
private String msg; |
||||
|
|
||||
|
ErrorCode(final int code, final String msg) { |
||||
|
this.code = code; |
||||
|
this.msg = msg; |
||||
|
} |
||||
|
|
||||
|
public static final int COMMON_ERR_CODE = -1; |
||||
|
|
||||
|
@Override |
||||
|
public int getCode() { |
||||
|
return code; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getMsg() { |
||||
|
return msg; |
||||
|
} |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
/** |
||||
|
* Copyright 2018 人人开源 http://www.renren.io
|
||||
|
* <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.elink.esua.common.token.interceptor; |
||||
|
|
||||
|
|
||||
|
import com.elink.esua.common.token.annotation.Login; |
||||
|
import com.elink.esua.common.token.dto.TokenDto; |
||||
|
import com.elink.esua.common.token.enums.ErrorCode; |
||||
|
import com.elink.esua.common.token.util.TokenUtil; |
||||
|
import com.elink.esua.epdc.commons.tools.constant.Constant; |
||||
|
import com.elink.esua.epdc.commons.tools.exception.RenException; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
import org.springframework.web.method.HandlerMethod; |
||||
|
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; |
||||
|
|
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import javax.servlet.http.HttpServletResponse; |
||||
|
|
||||
|
/** |
||||
|
* @author rongchao |
||||
|
* @Date 18-11-20 |
||||
|
*/ |
||||
|
@Component |
||||
|
public class AuthorizationInterceptor extends HandlerInterceptorAdapter { |
||||
|
|
||||
|
@Autowired |
||||
|
private TokenUtil tokenUtil; |
||||
|
|
||||
|
@Override |
||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
||||
|
Login annotation; |
||||
|
if (handler instanceof HandlerMethod) { |
||||
|
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class); |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if (annotation == null) { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
//从header中获取token
|
||||
|
String token = request.getHeader("Authorization"); |
||||
|
//如果header中不存在token,则从参数中获取token
|
||||
|
if (StringUtils.isEmpty(token)) { |
||||
|
token = request.getParameter("token"); |
||||
|
} |
||||
|
|
||||
|
//token为空
|
||||
|
if (StringUtils.isEmpty(token)) { |
||||
|
// 表示请求信息中没有携带token,前端需要修改上送数据
|
||||
|
throw new RenException(ErrorCode.ERR10005.getCode(), ErrorCode.ERR10005.getMsg()); |
||||
|
} |
||||
|
|
||||
|
//查询token信息
|
||||
|
TokenDto tokenDto = tokenUtil.getTokenInfo(); |
||||
|
if (tokenDto == null || tokenDto.getExpireTime().getTime() < System.currentTimeMillis()) { |
||||
|
// token失效或已被清除,前端需要重新请求获取token的接口,并上送
|
||||
|
throw new RenException(ErrorCode.ERR10001.getCode(), ErrorCode.ERR10001.getMsg()); |
||||
|
} |
||||
|
|
||||
|
//设置userId到request里,后续根据userId,获取用户信息
|
||||
|
request.setAttribute(Constant.APP_USER_KEY, tokenDto); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
package com.elink.esua.common.token.property; |
||||
|
|
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* @author rongchao |
||||
|
* @Date 18-12-3 |
||||
|
*/ |
||||
|
@Component |
||||
|
@ConfigurationProperties(prefix = "token") |
||||
|
public class TokenPropertise { |
||||
|
|
||||
|
private long expire = 7200L; |
||||
|
|
||||
|
public long getExpire() { |
||||
|
return expire; |
||||
|
} |
||||
|
|
||||
|
public void setExpire(long expire) { |
||||
|
this.expire = expire; |
||||
|
} |
||||
|
} |
@ -0,0 +1,68 @@ |
|||||
|
package com.elink.esua.common.token.util; |
||||
|
|
||||
|
import com.elink.esua.common.token.dto.TokenDto; |
||||
|
import com.elink.esua.common.token.dto.UserTokenDto; |
||||
|
import com.elink.esua.common.token.property.TokenPropertise; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
/** |
||||
|
* token服务类 |
||||
|
* |
||||
|
* @author rongchao |
||||
|
* @Date 18-10-31 |
||||
|
*/ |
||||
|
@Component |
||||
|
public class TokenUtil { |
||||
|
|
||||
|
private Logger logger = LoggerFactory.getLogger(getClass()); |
||||
|
|
||||
|
@Autowired |
||||
|
private TokenPropertise tokenPropertise; |
||||
|
|
||||
|
@Autowired |
||||
|
private CpUserDetailRedis redisUtils; |
||||
|
|
||||
|
public TokenDto getTokenInfo(String userId) { |
||||
|
TokenDto tokenDto = redisUtils.get(userId); |
||||
|
return tokenDto; |
||||
|
} |
||||
|
|
||||
|
public TokenDto createToken(UserTokenDto user) { |
||||
|
// 当前时间
|
||||
|
Date now = new Date(); |
||||
|
// 过期时间
|
||||
|
Date expireTime = new Date(now.getTime() + tokenPropertise.getExpire() * 1000); |
||||
|
|
||||
|
// 生成token
|
||||
|
String token = this.generateToken(); |
||||
|
|
||||
|
// 保存或更新用户token
|
||||
|
TokenDto tokenDto = new TokenDto(); |
||||
|
tokenDto.setUserInfoDto(user); |
||||
|
tokenDto.setToken(token); |
||||
|
tokenDto.setUpdateTime(now); |
||||
|
tokenDto.setExpireTime(expireTime); |
||||
|
redisUtils.set(tokenDto, tokenPropertise.getExpire()); |
||||
|
return tokenDto; |
||||
|
} |
||||
|
|
||||
|
public void expireToken(String userId) { |
||||
|
redisUtils.logout(userId); |
||||
|
} |
||||
|
|
||||
|
public boolean delayToken(String token) { |
||||
|
return redisUtils.expire(token, tokenPropertise.getExpire()); |
||||
|
} |
||||
|
|
||||
|
private String generateToken() { |
||||
|
return UUID.randomUUID().toString().replace("-", ""); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,56 @@ |
|||||
|
package com.elink.esua.common.token.util; |
||||
|
|
||||
|
import com.elink.esua.common.token.dto.TokenDto; |
||||
|
import com.elink.esua.common.token.dto.UserTokenDto; |
||||
|
import com.elink.esua.common.token.interceptor.AuthorizationInterceptor; |
||||
|
import com.elink.esua.epdc.commons.tools.utils.WebUtil; |
||||
|
|
||||
|
/** |
||||
|
* 用户工具类 |
||||
|
* |
||||
|
* @author rongchao |
||||
|
* @Date 18-11-20 |
||||
|
*/ |
||||
|
public class UserUtil { |
||||
|
|
||||
|
/** |
||||
|
* 获取当前用户信息 |
||||
|
* |
||||
|
* @return |
||||
|
*/ |
||||
|
public static TokenDto getCurrentUser() { |
||||
|
return (TokenDto) WebUtil.getAttributesFromRequest(AuthorizationInterceptor.USER_KEY); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取当前用户信息 |
||||
|
* |
||||
|
* @return com.elink.esua.common.token.dto.UserTokenDto |
||||
|
* @author yujintao |
||||
|
* @date 2018/12/5 9:24 |
||||
|
*/ |
||||
|
public static UserTokenDto getCurrentUserInfo() { |
||||
|
TokenDto tokenDto = getCurrentUser(); |
||||
|
if (tokenDto == null || tokenDto.getUserInfoDto() == null) { |
||||
|
return null; |
||||
|
} |
||||
|
return tokenDto.getUserInfoDto(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取当前用户ID |
||||
|
* |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String getCurrentUserId() { |
||||
|
TokenDto tokenDto = getCurrentUser(); |
||||
|
if (tokenDto == null || tokenDto.getUserInfoDto() == null) { |
||||
|
return null; |
||||
|
} |
||||
|
return tokenDto.getUserInfoDto().getUserId(); |
||||
|
} |
||||
|
|
||||
|
public static void setCurrentUser(TokenDto user) { |
||||
|
WebUtil.setAttributesFromRequest(AuthorizationInterceptor.USER_KEY, user); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue