登录功能实现与JWT令牌

这一篇文章主要实现登录功能以及会话技术的介绍包括cookie、session和JWT令牌的使用

        下面开始


登录功能

基本登录

思路

开发

新建loginController文件

  • Controller

  • package com.testpeople.controller;
    
    import com.testpeople.pojo.Emp;
    import com.testpeople.pojo.Result;
    import com.testpeople.service.EmpService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    
    @Slf4j
    @RestController
    public class LoginController {
    
    
        @Autowired
        private EmpService empService;
    
        /**
         * 员工登录功能接口
         * @param emp
         * @return
         */
        @PostMapping("/login")
        public Result login(@RequestBody Emp emp){
            //输出日志
            log.info("员工登录:{}",emp);
            Emp e = empService.login(emp);
            return e != null ? Result.success():Result.error("用户名或密码错误");
        }
    
    
    
    }
  • Service

  • /**
     * 根据用户名和密码查询员工信息
     * @param emp
     * @return
     */
    @Override
    public Emp login(Emp emp) {
    
        return empMapper.getByUsernameAndPassword(emp);
    
    }
  • Mapper

  • /**
     * 根据用户名和密码查询员工信息
     * @param emp
     * @return
     */
    @Select("select * from emp where username = #{username} and password = #{password}")
    Emp getByUsernameAndPassword(Emp emp);
    测试
  • Postman

  • 前后端联调

登录校验

会话技术

  • Cookie

  • 测试

  • package com.testpeople.controller;
    
    
    import com.testpeople.pojo.Result;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Cookie 演示
     */
    @Slf4j
    @RestController
    public class SessionController {
    
        //设置Cookie
        @GetMapping("/c1")
        public Result cookie1(HttpServletResponse response){
            response.addCookie(new Cookie("login_username","testPeople"));
            return Result.success();
        }
    
        //获取Cookie
        @GetMapping("/c2")
        public Result cookie2(HttpServletRequest request){
            Cookie[] cookies = request.getCookies(); // 获取所有cookie
            for (Cookie cookie : cookies){
                if(cookie.getName().equals("login_username")){ //输出名字为login_username的cookie
                    System.out.println("login_uername"+cookie.getValue());
                }
            }
            return Result.success();
        }
    
    
    }
  • c1效果

  • c2效果

  • Session

  • 测试

  • //在HttpSession中存储
    @GetMapping("/s1")
    public Result session1(HttpSession session){
        log.info("HttpSession:{}",session.hashCode());
        session.setAttribute("loginUser","tom"); //在session中存储数据
        return Result.success();
    }
    
    //从HttpSession中获取
    @GetMapping("/s2")
    public Result session2(HttpServletRequest request){
        HttpSession session = request.getSession();
        log.info("HttpSession-s2:{}",session.hashCode());
        Object loginUser = session.getAttribute("loginUser"); //从session中获取数据
        log.info("loginUser:{}",loginUser);
        return Result.success(loginUser);
    }
  • s1效果

  • s2效果

  • 后台效果

  • 令牌

JWT令牌
  • 简介

  • 应用场景(登录认证)

  • 使用

    • 引入

    • <!--        用于JWT令牌验证-->
      <dependency>
          <groupId>io.jsonwebtoken</groupId>
          <artifactId>jjwt</artifactId>
          <version>0.9.1</version>
      </dependency>
    • 测试

    • 
       * 用于生成jwt令牌
       */
      @Test
      void jwtTest(){
      
          Map<String,Object> claims = new HashMap<>();
      
          //测试数据
          claims.put("id",1000L);
          claims.put("name","Tom");
      
      
          String jwt = Jwts.builder()
                  .signWith(SignatureAlgorithm.HS256, "testPeo")//设置签名算法
                  .setClaims(claims)//设置自定义数据(载荷)
                  .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) //设置有效时间为1小时
                  .compact();
          System.out.printf(jwt);
      }
      
      
      /**
       * 用于解析JWT令牌
       * @param
       */
      @Test
      void parseJwt() {
          Claims claims = Jwts.parser()
                  .setSigningKey("testPeo")
                  .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVG9tIiwiaWQiOjEwMDAsImV4cCI6MTcxOTM3NjE5N30.31fbBJ_iwfV29ca1gOst8KStuKMKMtMfvcULE_dX1BE")
                  .getBody();
          System.out.printf(claims.toString());
      
      }
  • 注意

    • Jwt校验时使用的签名密钥,必须和生成的该令牌时使用的密钥相同。

    • Jwt令牌报错则表示,Jwt令牌被修改、失效、非法等。

  • 应用于登录校验

  • 开发

    • 工具类Jwt

    • package com.testpeople.utils;
      
      import io.jsonwebtoken.Claims;
      import io.jsonwebtoken.Jwts;
      import io.jsonwebtoken.SignatureAlgorithm;
      import org.springframework.stereotype.Component;
      
      import java.util.Date;
      import java.util.Map;
      
      @Component
      public class JwtUtils {
      
      
          private static String singningKey = "TestPeo";
          private static long expiration = 43200000L;
      
      
          /**
           * 生成Jwt令牌
           * @param claims
           * @return
           */
          public static String generateJwt(Map<String,Object> claims){
      
              String jwt = Jwts.builder()
                      .addClaims(claims)
                      .signWith(SignatureAlgorithm.HS256, singningKey)
                      .setExpiration(new Date(System.currentTimeMillis() + expiration))
                      .compact();
              return jwt;
      
          }
      
          /**\
           * 解析Jwt令牌
           * @param jwt
           * @return
           */
          public static Claims parseJwt(String jwt){
              Claims claims = Jwts.parser()
                      .setSigningKey(singningKey)
                      .parseClaimsJws(jwt)
                      .getBody();
              return claims;
          }
      
      
      
      }
    • Controller

    • /**
       * 员工登录功能接口
       * @param emp
       * @return
       */
      @PostMapping("/login")
      public Result login(@RequestBody Emp emp){
          //输出日志
          log.info("员工登录:{}",emp);
          Emp e = empService.login(emp);
      
          //登陆成功生成令牌,并发送令牌
      
          if (e != null){
      
              Map<String, Object> claims = new HashMap<>();
      
              claims.put("id",e.getId());
              claims.put("name",e.getName());
              claims.put("username",e.getUsername());
              String jwt = JwtUtils.generateJwt(claims);
      
              return Result.success(jwt);
      
          }
          //登录失败,返回错误信息
          else {
              return Result.error("用户名或密码错误");
          }
      
      
      }
    • 测试

      • Postman

  • 前后端联调

  • 效果

    • 携带的请求头中有Token

    • 其中Token中的数据为Jwt令牌生成的数据

  • 注意

    • java8之后删除了这个包,使用是会报错。

    • <!--        解决一个错误关于Jwt令牌的问题-->
          <dependency>
              <groupId>javax.xml.bind</groupId>
              <artifactId>jaxb-api</artifactId>
              <version>2.3.1</version>
          </dependency>

 以上知识,来自小编学习黑马程序员的课程。


以下是项目链接

黑马程序员项目javaWebjavaWeb开发学习仓库


  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用JWT令牌实现登录功能可以增加系统的安全性和可扩展性。下面是一个基本的实现过程: 1. 用户通过用户名和密码进行登录请求。 2. 服务器验证用户的身份,并生成一个JWT令牌。 3. 服务器将JWT令牌发送给客户端作为登录凭证。 4. 客户端在后续的请求中将JWT令牌携带在请求头或者请求参数中。 5. 服务器在接收到请求时验证JWT令牌的有效性和签名。 6. 如果JWT令牌有效,则处理请求;否则,返回未授权的错误。 下面是一个示例代码(使用Node.js和jsonwebtoken库): ```javascript const jwt = require('jsonwebtoken'); // 登录处理 function login(username, password) { // 验证用户名和密码,生成用户对象 const user = authenticateUser(username, password); if (user) { // 生成JWT令牌 const token = jwt.sign({ id: user.id }, 'your_secret_key', { expiresIn: '1h' }); return token; } else { throw new Error('Invalid username or password'); } } // 请求处理中间件 function authenticateToken(req, res, next) { // 获取请求头中的Authorization字段 const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (token == null) { return res.sendStatus(401); // 未授权 } // 验证JWT令牌 jwt.verify(token, 'your_secret_key', (err, user) => { if (err) { return res.sendStatus(403); // 令牌无效 } req.user = user; next(); // 验证通过,继续处理请求 }); } // 示例路由,需要进行身份验证 app.get('/protected', authenticateToken, (req, res) => { res.send('Protected data'); }); ``` 在上面的示例中,`login`函数用于生成JWT令牌。`authenticateToken`函数是一个请求处理中间件,用于验证JWT令牌的有效性。 注意,在实际使用中,你需要替换示例中的`your_secret_key`为一个安全的密钥,并根据自己的需求进行相应的调整。 希望这个例子能够帮到你,如果有更多问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值