From 84166a39f9c14e45b50fc6b73ae5c26523364de2 Mon Sep 17 00:00:00 2001 From: rongchao Date: Thu, 5 Sep 2019 14:15:09 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../epdc-common-clienttoken/pom.xml | 120 ++++++++++++++++++ .../esua/common/token/annotation/Login.java | 31 +++++ .../common/token/annotation/LoginUser.java | 35 +++++ .../token/annotation/NeedClientToken.java | 13 ++ .../elink/esua/common/token/dto/TokenDto.java | 38 ++++++ .../esua/common/token/dto/UserTokenDto.java | 43 +++++++ .../esua/common/token/enums/ErrorCode.java | 46 +++++++ .../interceptor/AuthorizationInterceptor.java | 83 ++++++++++++ .../token/property/TokenPropertise.java | 23 ++++ .../esua/common/token/util/TokenUtil.java | 68 ++++++++++ .../esua/common/token/util/UserUtil.java | 56 ++++++++ 11 files changed, 556 insertions(+) create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/pom.xml create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/Login.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/LoginUser.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/NeedClientToken.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/TokenDto.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/UserTokenDto.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/enums/ErrorCode.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/interceptor/AuthorizationInterceptor.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/property/TokenPropertise.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/TokenUtil.java create mode 100644 esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/UserUtil.java diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/pom.xml b/esua-epdc/epdc-commons/epdc-common-clienttoken/pom.xml new file mode 100644 index 000000000..e6c04ec31 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/pom.xml @@ -0,0 +1,120 @@ + + + + + epdc-commons + com.esua.epdc + 1.0.0 + + 4.0.0 + + epdc-common-clienttoken + jar + + epdc-common-clienttoken + http://www.example.com + 客户端token + + + + com.esua.epdc + epdc-commons-tools + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + provided + + + + org.springframework.boot + spring-boot-starter-aop + provided + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + com.vaadin.external.google + android-json + + + + + + org.springframework.boot + spring-boot-autoconfigure + compile + + + + org.springframework.boot + spring-boot-autoconfigure-processor + compile + true + + + + org.springframework.boot + spring-boot-starter-log4j2 + provided + + + + + ${project.artifactId} + + + + maven-clean-plugin + + + + maven-resources-plugin + + + maven-compiler-plugin + + true + ${maven.compiler.source} + ${maven.compiler.target} + ${project.build.sourceEncoding} + + + + maven-surefire-plugin + + + maven-war-plugin + + + maven-install-plugin + + + maven-deploy-plugin + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + + + + + + + ${project.basedir}/src/main/java + + diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/Login.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/Login.java new file mode 100644 index 000000000..3eead233b --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/Login.java @@ -0,0 +1,31 @@ +/** + * Copyright 2018 人人开源 http://www.renren.io + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 { +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/LoginUser.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/LoginUser.java new file mode 100644 index 000000000..9fdaae4c9 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/LoginUser.java @@ -0,0 +1,35 @@ +/** + * Copyright 2018 人人开源 http://www.renren.io + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 { + +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/NeedClientToken.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/NeedClientToken.java new file mode 100644 index 000000000..ff6e5fbe5 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/annotation/NeedClientToken.java @@ -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; +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/TokenDto.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/TokenDto.java new file mode 100644 index 000000000..90fe6269a --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/TokenDto.java @@ -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; +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/UserTokenDto.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/UserTokenDto.java new file mode 100644 index 000000000..0e2478ef1 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/dto/UserTokenDto.java @@ -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; +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/enums/ErrorCode.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/enums/ErrorCode.java new file mode 100644 index 000000000..0f8a8bc3a --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/enums/ErrorCode.java @@ -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; + } +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/interceptor/AuthorizationInterceptor.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/interceptor/AuthorizationInterceptor.java new file mode 100644 index 000000000..90f924370 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/interceptor/AuthorizationInterceptor.java @@ -0,0 +1,83 @@ +/** + * Copyright 2018 人人开源 http://www.renren.io + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + } +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/property/TokenPropertise.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/property/TokenPropertise.java new file mode 100644 index 000000000..06fa24477 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/property/TokenPropertise.java @@ -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; + } +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/TokenUtil.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/TokenUtil.java new file mode 100644 index 000000000..96aedcaba --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/TokenUtil.java @@ -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("-", ""); + } + + +} diff --git a/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/UserUtil.java b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/UserUtil.java new file mode 100644 index 000000000..c69067be1 --- /dev/null +++ b/esua-epdc/epdc-commons/epdc-common-clienttoken/src/main/java/com/elink/esua/common/token/util/UserUtil.java @@ -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); + } +}