后端登录安全的一种思路

PS:作者是小白能接触到的就只会这样写。勿喷。

前提

思路: 结合io流将登录token存储到配置文件中,不将token存储到浏览器端,从而避免盗取。

下面jwt的学习可以参考下这个:

JWT --- 入门学习_本郡主是喵的博客-CSDN博客

JWT工具类

java 复制代码
@Component
public class JWTtUtils {

    public static final String USER_NAME = "username";
    public static final String PASS_WORD = "password";
    public static final String CREATE_TIME = "createTime";
    public static final String SIGN_KEY = "QHX2004"; // 解析key
    /**
     * 用用户名和密码生成JWT
     *
     * @param username
     * @param password
     * @return
     */

    public String generatorJWTFromUserNameAndPassword(String username,String password){
        HashMap<String, Object> hashMap = new HashMap<>(); // 生成map
        hashMap.put(USER_NAME,username);
        hashMap.put(PASS_WORD,password);
        hashMap.put(CREATE_TIME,new Date());
        return  generatorJWTFromUserNameAndPassword(hashMap);
    }

    /**
     * 生成jwt过期时间,1个月
     *
     * @param
     * @return
     */
    private Date generatorExpirationDate() {
        return new Date(System.currentTimeMillis() + (1000L * 60 * 60 *24 *30));
    }

    /**
     * 用用户名和密码生成jwt
     *
     * @param paramMap
     * @return
     */
    private String generatorJWTFromUserNameAndPassword(HashMap<String, Object> paramMap) {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setClaims(paramMap)
                .setExpiration(generatorExpirationDate()) // 设置过期时间
                .signWith(SignatureAlgorithm.HS512,SIGN_KEY);
        return jwtBuilder.compact(); // 拿到token
    }



    /**
     * 解析token拿到Claims
     *
     *
     * @param token
     * @return
     */
     private Claims getClaimsFromToken(String token){
        Claims claims = Jwts.parser()
                .setSigningKey(SIGN_KEY)
                .parseClaimsJws(token)
                .getBody();

        return claims;
    }

    /**
     * 校验token是否过期
     *
     * @param token
     * @return
     */
  // 过期返回true
    public boolean checkTokenIsOverdue(String token){
        Claims claims = getClaimsFromToken(token);
        Date date =  claims.getExpiration();
        return date.getTime() < new Date().getTime();
    }


    /**
     * 刷新token:重新生成一个token
     *
     * @param
     * @return
     */

    public String flushToken(String token){
        Claims claims = getClaimsFromToken(token);
        String username = (String) claims.get(USER_NAME);
        String password = (String)claims.get(PASS_WORD);
        return generatorJWTFromUserNameAndPassword(username,password);
    }

}

IO工具类

java 复制代码
public class IOUtils {


    public static final String FILE_NAME = "conf.properties";

    /**
     *   配置文件读取
     * @param key
     * @return  value
     */

    public static String getPropertiesKey(String key)  {
      return  getKey(key);
    }

    /**
     * 配置文件读取
     *
     * @param  key
     * @return
     */
    private static String getKey(String key) {
        Properties properties = new Properties();
        File file = new File(FILE_NAME);
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            properties.load(inputStream); // 其实已经将配置文件拿到手了
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(inputStream != null){  // 还是这样关比较好,万一报错就tm关不了
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return  properties.getProperty(key);
    }

    /**
     * 配置文件设置
     *
     * @param key
     * @param value
     * @return
     */
    public static boolean setPropertiesKey(String key,String value) {
        // 判断key是否有重复
        String key1 = getKey(key);
        if(key1 == null){
            return setKey(key,value); // 把核心业务逻辑抽出来
        }
        return false;
    }

    /**
     *  配置文件设置
     *
     * @param key
     * @param value
     * @return boolean
     */
    private static boolean setKey(String key, String value) {
        Properties properties = new Properties();
        File file = new File(FILE_NAME); // 其实有其他配置可以同意下yaml文件里面配置,然后这里面读取,好统一调配。
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(file,true);
            properties.setProperty(key, value); // 存进map里面
            properties.store(fileWriter,""); // 将map对应的键值对写进输出流。
        } catch (IOException e) {
            // 卧槽我加入设置key,value失败,肯定调到这个逻辑
            return false;
        } finally {
            if (fileWriter != null) {  // 还是这样关比较好,万一报错就tm关不了
                try {
                    fileWriter.flush();
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

}

测试文件

java 复制代码
@SpringBootTest
class IoDemoApplicationTests {

    @Test
    void contextLoads() {
        // 用户第一登录 ----,我们这里浏览器端不存token,只存用户名,更安全。
        String username = "qhx2005";
        String password = "123456";
        // 生成jwt
        JWTtUtils jwTtUtils = new JWTtUtils();
        String token = jwTtUtils.generatorJWTFromUserNameAndPassword(username, password);
        // 将jwt存进配置文件
        boolean success = IOUtils.setPropertiesKey(username, token);
        System.out.println("存进配置文件成功状态:"+success);
        assert success;


        // 用户登录后访问其他页面。检验token过期,拿出配置文件是否存在----
        // 获取token
        String token1 = IOUtils.getPropertiesKey(username);
        System.out.println(token1);
        // 检验token是否过期
        boolean overdue = jwTtUtils.checkTokenIsOverdue(token);
        // 本来这里如果token过期,我们响应一个状态码,让前端axios过滤器捕获到,删除本地username,重定向到登录页。
        System.out.println("已经过期:"+overdue);

    }

}
相关推荐
2301_780789666 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
第九序言T7 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
学长毕设7 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn8 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川8 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵8 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
程序喵大人8 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
秋天的怀念_David8 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1008 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin9 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php