From 7334501440c9d0ad92837d3864f7f441bdf65a69 Mon Sep 17 00:00:00 2001 From: zwzw1219 Date: Mon, 25 Dec 2017 10:28:32 +0800 Subject: [PATCH] !6 db-token Merge pull request !6 from zwzw1219/token-config --- doc/db/boot_security.sql | 12 +++ ...\345\217\212\351\205\215\347\275\256.docx" | Bin 852389 -> 881331 bytes .../boot/security/server/dao/TokenDao.java | 25 +++++ .../boot/security/server/dto/LoginUser.java | 4 + .../security/server/model/TokenModel.java | 34 ++++++ .../security/server/service/TokenService.java | 7 +- .../service/impl/TokenServiceDbImpl.java | 99 ++++++++++++++++++ .../server/service/impl/TokenServiceImpl.java | 8 ++ 8 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/boot/security/server/dao/TokenDao.java create mode 100644 src/main/java/com/boot/security/server/model/TokenModel.java create mode 100644 src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java diff --git a/doc/db/boot_security.sql b/doc/db/boot_security.sql index 1cc36a3..3071eb9 100644 --- a/doc/db/boot_security.sql +++ b/doc/db/boot_security.sql @@ -542,3 +542,15 @@ CREATE TABLE `t_notice_read` ( -- ---------------------------- -- Records of t_notice_read -- ---------------------------- +-- ---------------------------- +-- Table structure for t_token +-- ---------------------------- +DROP TABLE IF EXISTS `t_token`; +CREATE TABLE `t_token` ( + `id` varchar(36) NOT NULL COMMENT 'token', + `val` text NOT NULL COMMENT 'LoginUser的json串', + `expireTime` datetime NOT NULL, + `createTime` datetime NOT NULL, + `updateTime` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file diff --git "a/doc/\346\241\206\346\236\266\345\217\212\351\205\215\347\275\256.docx" "b/doc/\346\241\206\346\236\266\345\217\212\351\205\215\347\275\256.docx" index 3d4701d8de562386269886afb6b3d70585f057c0..4e8ba32e5a246a8628fea8f1af533d08f8d0ec0b 100644 GIT binary patch delta 43903 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 delta 14912 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 V1mdC4LC`_ieNaincmGb^{|A*@H0b~U diff --git a/src/main/java/com/boot/security/server/dao/TokenDao.java b/src/main/java/com/boot/security/server/dao/TokenDao.java new file mode 100644 index 0000000..9bdf37f --- /dev/null +++ b/src/main/java/com/boot/security/server/dao/TokenDao.java @@ -0,0 +1,25 @@ +package com.boot.security.server.dao; + +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; + +import com.boot.security.server.model.TokenModel; + +@Mapper +public interface TokenDao { + + @Insert("insert into t_token(id, val, expireTime, createTime, updateTime) values (#{id}, #{val}, #{expireTime}, #{createTime}, #{updateTime})") + int save(TokenModel model); + + @Select("select * from t_token t where t.id = #{id}") + TokenModel getById(String id); + + @Update("update t_token t set t.val = #{val}, t.expireTime = #{expireTime}, t.updateTime = #{updateTime} where t.id = #{id}") + int update(TokenModel model); + + @Delete("delete from t_token where id = #{id}") + int delete(String id); +} diff --git a/src/main/java/com/boot/security/server/dto/LoginUser.java b/src/main/java/com/boot/security/server/dto/LoginUser.java index 9b2a481..d1bf792 100644 --- a/src/main/java/com/boot/security/server/dto/LoginUser.java +++ b/src/main/java/com/boot/security/server/dto/LoginUser.java @@ -47,6 +47,10 @@ public class LoginUser extends SysUser implements UserDetails { .map(p -> new SimpleGrantedAuthority(p.getPermission())).collect(Collectors.toSet()); } + public void setAuthorities(Collection authorities) { + // do nothing + } + // 账户是否未过期 @JsonIgnore @Override diff --git a/src/main/java/com/boot/security/server/model/TokenModel.java b/src/main/java/com/boot/security/server/model/TokenModel.java new file mode 100644 index 0000000..79bc28a --- /dev/null +++ b/src/main/java/com/boot/security/server/model/TokenModel.java @@ -0,0 +1,34 @@ +package com.boot.security.server.model; + +import java.util.Date; + +public class TokenModel extends BaseEntity { + + private static final long serialVersionUID = 4566334160572911795L; + + /** + * 过期时间 + */ + private Date expireTime; + /** + * LoginUser的json串 + */ + private String val; + + public Date getExpireTime() { + return expireTime; + } + + public void setExpireTime(Date expireTime) { + this.expireTime = expireTime; + } + + public String getVal() { + return val; + } + + public void setVal(String val) { + this.val = val; + } + +} diff --git a/src/main/java/com/boot/security/server/service/TokenService.java b/src/main/java/com/boot/security/server/service/TokenService.java index 6b1dc98..9c68e39 100644 --- a/src/main/java/com/boot/security/server/service/TokenService.java +++ b/src/main/java/com/boot/security/server/service/TokenService.java @@ -4,7 +4,12 @@ import com.boot.security.server.dto.LoginUser; import com.boot.security.server.dto.Token; /** - * Token管理器 + * Token管理器
+ * 可存储到redis或者数据库
+ * 具体可看实现类
+ * 默认基于redis,实现类为 com.boot.security.server.service.impl.TokenServiceImpl
+ * 如要换成数据库存储,将TokenServiceImpl类上的注解@Primary挪到com.boot.security.server.service.impl.TokenServiceDbImpl + * * * @author 小威老师 * diff --git a/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java b/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java new file mode 100644 index 0000000..697ebfb --- /dev/null +++ b/src/main/java/com/boot/security/server/service/impl/TokenServiceDbImpl.java @@ -0,0 +1,99 @@ +package com.boot.security.server.service.impl; + +import java.util.Date; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.alibaba.fastjson.JSONObject; +import com.boot.security.server.dao.TokenDao; +import com.boot.security.server.dto.LoginUser; +import com.boot.security.server.dto.Token; +import com.boot.security.server.model.TokenModel; +import com.boot.security.server.service.SysLogService; +import com.boot.security.server.service.TokenService; + +/** + * token存到数据库的实现类 + * + * @author 小威老师 + * + */ +@Service +public class TokenServiceDbImpl implements TokenService { + + /** + * token过期秒数 + */ + @Value("${token.expire.seconds}") + private Integer expireSeconds; + @Autowired + private TokenDao tokenDao; + @Autowired + private SysLogService logService; + + @Override + public Token saveToken(LoginUser loginUser) { + String token = UUID.randomUUID().toString(); + + loginUser.setToken(token); + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000); + + TokenModel model = new TokenModel(); + model.setId(token); + model.setCreateTime(new Date()); + model.setUpdateTime(new Date()); + model.setExpireTime(new Date(loginUser.getExpireTime())); + model.setVal(JSONObject.toJSONString(loginUser)); + + tokenDao.save(model); + // 登陆日志 + logService.save(loginUser.getId(), "登陆", true, null); + + return new Token(token, loginUser.getLoginTime()); + } + + @Override + public void refresh(LoginUser loginUser) { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000); + + TokenModel model = tokenDao.getById(loginUser.getToken()); + model.setUpdateTime(new Date()); + model.setExpireTime(new Date(loginUser.getExpireTime())); + model.setVal(JSONObject.toJSONString(loginUser)); + + tokenDao.update(model); + } + + @Override + public LoginUser getLoginUser(String token) { + TokenModel model = tokenDao.getById(token); + return toLoginUser(model); + } + + @Override + public boolean deleteToken(String token) { + TokenModel model = tokenDao.getById(token); + LoginUser loginUser = toLoginUser(model); + if (loginUser != null) { + tokenDao.delete(token); + logService.save(loginUser.getId(), "退出", true, null); + + return true; + } + + return false; + } + + private LoginUser toLoginUser(TokenModel model) { + if (model == null) { + return null; + } + return JSONObject.parseObject(model.getVal(), LoginUser.class); + } + +} diff --git a/src/main/java/com/boot/security/server/service/impl/TokenServiceImpl.java b/src/main/java/com/boot/security/server/service/impl/TokenServiceImpl.java index ef92d9b..968a4c2 100644 --- a/src/main/java/com/boot/security/server/service/impl/TokenServiceImpl.java +++ b/src/main/java/com/boot/security/server/service/impl/TokenServiceImpl.java @@ -5,6 +5,7 @@ import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -13,6 +14,13 @@ import com.boot.security.server.dto.Token; import com.boot.security.server.service.SysLogService; import com.boot.security.server.service.TokenService; +/** + * token存到redis的实现类 + * + * @author 小威老师 + * + */ +@Primary @Service public class TokenServiceImpl implements TokenService { -- Gitee