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