登录认证,登录校验

一、基础登录功能

 1.Controller层

import com.itheima.pojo.Emp;
import com.itheima.pojo.Result;
import com.itheima.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;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        log.info ( "登录用户名:{},密码:{}",emp );
    Emp e =empService.login(emp);
        return e!=null?Result.success ():Result.error ( "用户名或密码错误" );

    }
}

2.Service层

    @Override
    public Emp login(Emp emp) {
        return empMapper.getByusernameAndPassword(emp);
    }
}

3.Mapper层

 /**
     * 根据用户名密码查询员工
     * @param emp
     * @return
     */

    @Select ( "select * from emp where username=#{username} and password=#{password}")
    Emp getByusernameAndPassword(Emp emp);

二、登录校验

1.会话技术

1.会话跟踪方案对比


import com.itheima.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;
import javax.servlet.http.HttpSession;

/**
 * HttpSession演示
 */
@Slf4j
@RestController
public class SessionController {

    //设置Cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response){
        response.addCookie(new Cookie("login_username","itheima")); //设置Cookie/响应Cookie
        return Result.success();
    }

    //获取Cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals("login_username")){
                System.out.println("login_username: "+cookie.getValue()); //输出name为login_username的cookie
            }
        }
        return Result.success();
    }



    @GetMapping("/s1")
    public Result session1(HttpSession session){
        log.info("HttpSession-s1: {}", session.hashCode());

        session.setAttribute("loginUser", "tom"); //往session中存储数据
        return Result.success();
    }

    @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);
    }
}

2.JWT令牌技术

/**
     * 测试Jwt令牌的生成
     */
    @Test
    public void testGenJwt(){
        Map<String, Object> claims=new HashMap<> ();
        claims.put ( "id",1 );
        claims.put ( "name","TOM" );
        String jwt = Jwts.builder ()
                .signWith ( SignatureAlgorithm.HS256, "itheima" )//签名算法
                .setClaims ( claims )//自定义内容(载荷)
                .setExpiration ( new Date ( System.currentTimeMillis ()  ) )
//                .setExpiration ( new Date ( System.currentTimeMillis () + 3600 * 1000 ) )//设置令牌的有效期为1个小时
                .compact ();//返回一个jwt令牌
        System.out.println (jwt);
    }

1.生成JWT令牌

2.令牌解析

    @Test
    public void testPrasejwt(){
        Claims claims = Jwts.parser ()
                .setSigningKey ( "itheima" )
                .parseClaimsJws ( "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVE9NIiwiaWQiOjEsImV4cCI6MTY5NzAwOTgwN30.9iduxbB4vpQLGs3anczG-spuQdT5f_3BR6aHYYHop3M" )
                .getBody ();
        System.out.println ( claims );
    }

3.登陆后下发令牌

1.jwtUtils类
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

    private static String signKey = "itheima";
    private static Long expire = 43200000L;

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }
}
2.Controller层
import com.itheima.pojo.Emp;
import com.itheima.pojo.Result;
import com.itheima.service.EmpService;
import com.itheima.utils.JwtUtils;
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;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class LoginController {
    @Autowired
    private EmpService empService;

    @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.getUsername () );
        claims.put ( "username",e.getUsername () );
        String jwt = JwtUtils.generateJwt ( claims );//jwt 包含了当前登录的员工信息
        return Result.success (jwt);//下发jwt令牌
    }

    //登录失败,返回错误信息
        return Result.error ( "用户名或密码错误" );

    }
}

三、过滤器 -Filter

1.入门程序

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override //初始化方法只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println ("初始化方法被调用了");
    }

    @Override   //拦截到请求之后调用
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        System.out.println ("拦截到了请求");
        chain.doFilter ( servletRequest,servletResponse );//放行
    }

    @Override //销毁方法,只调用一次
    public void destroy() {
        System.out.println ("销毁方法被调用了");
    }
}

2.Filter详解

1.Filter执行流程

2.过滤器的拦截路径

3.过滤器链

3.Filter完成登录校验

1.LoginCheckFilter

import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
    //1.获取请求url
        String url = req.getRequestURI ().toString ();
        log.info ( "请求的url:{}",url );
    //2.判断请求url中是否包含login,如果包含,说明是登陆操作,放行
        if (url.contains ( "login" )){
            log.info ("登陆操作,放行...");
            filterChain.doFilter (servletRequest,servletResponse  );
            return;
        }
    //3.获取请求头的令牌(token)
        String jwt = req.getHeader ( "token" );

    //4.判断令牌是否存在,如果不存在,返错误结果(未登录)
    if (!StringUtils.hasLength ( jwt )){
        log.info ( "请求头token为空,返回未登录的信息" );
        Result error = Result.error ( "NOT_LOGIN" );
        //手动转换Josn数据
        String notLogin = JSONObject.toJSONString ( error );
        resp.getWriter ().write ( notLogin );
        return;
    }
    //5.解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT ( jwt );
        } catch (Exception e) {
            e.printStackTrace ();
            log.info ( "解析令牌失败,返回未登录错误信息" );
            Result error = Result.error ( "NOT_LOGIN" );
            //手动转换Josn数据
            String notLogin = JSONObject.toJSONString ( error );
            resp.getWriter ().write ( notLogin );
            return;
        }
        //6.放行
        log.info ( "令牌合法,放行" );
        filterChain.doFilter ( servletRequest,servletResponse );
    }
}

2.手动将字符串转换为JSON格式数据

 //手动转换Josn数据
        String notLogin = JSONObject.toJSONString ( error );
        resp.getWriter ().write ( notLogin );

3.引入依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>

四、拦截器

1.拦截器的基本使用

1.定义拦截器

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override//目标资源方法运行前运行,返回true 放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println ("preHandle...");
        return true;
    }

    @Override//目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println ("postHandle.....");
    }

    @Override//视图渲染完毕后,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println ("afterCompletion...");
    }
}

2.配置拦截器

import com.itheima.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration//配置类
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor ( loginCheckInterceptor ).addPathPatterns ( "/**" );
    }
}

2.拦截路径,执行流程

 3.拦截器完成登录校验

import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
//@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
    //1.获取请求url
        String url = req.getRequestURI ().toString ();
        log.info ( "请求的url:{}",url );
    //2.判断请求url中是否包含login,如果包含,说明是登陆操作,放行
        if (url.contains ( "login" )){
            log.info ("登陆操作,放行...");
            filterChain.doFilter (servletRequest,servletResponse  );
            return;
        }
    //3.获取请求头的令牌(token)
        String jwt = req.getHeader ( "token" );

    //4.判断令牌是否存在,如果不存在,返错误结果(未登录)
    if (!StringUtils.hasLength ( jwt )){
        log.info ( "请求头token为空,返回未登录的信息" );
        Result error = Result.error ( "NOT_LOGIN" );
        //手动转换Josn数据
        String notLogin = JSONObject.toJSONString ( error );
        resp.getWriter ().write ( notLogin );
        return;
    }
    //5.解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT ( jwt );
        } catch (Exception e) {
            e.printStackTrace ();
            log.info ( "解析令牌失败,返回未登录错误信息" );
            Result error = Result.error ( "NOT_LOGIN" );
            //手动转换Josn数据
            String notLogin = JSONObject.toJSONString ( error );
            resp.getWriter ().write ( notLogin );
            return;
        }
        //6.放行
        log.info ( "令牌合法,放行" );
        filterChain.doFilter ( servletRequest,servletResponse );
    }
}

五、异常处理

import com.itheima.pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)//捕获异常的类型
 public Result ex(Exception exception){
        return Result.error ( "对不起操作失败,请联系管理员" );
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Core是一个跨平台的开源框架,用于构建现代化的云端应用程序。JWT(JSON Web Token)是一种用于身份验证和信息传递的开放标准(RFC 7519),通常用于前后端分离的应用中进行用户身份验证和授权。 在ASP.NET Core中,我们可以使用JWT来进行用户的登录校验。首先,我们需要服务器端生成JWT,并在用户登录成功后将JWT返回给客户端。客户端在之后的每次请求中都需要在请求头中携带JWT。服务器端收到请求后会从JWT中解析出用户信息并校验用户身份。 为了实现JWT登录校验,我们需要在ASP.NET Core应用中添加JWT认证中间件,并配置JWT的签名密钥、过期时间等参数。在用户登录成功后,我们可以使用JWT生成器来创建并返回JWT token。在客户端发送请求时,我们可以使用JWT验证器来验证JWT token,并根据验证结果进行相应的操作。 除了在服务器端进行JWT登录校验之外,我们还需要在客户端进行JWT的存储和管理。一般来说,客户端可以将JWT保存在本地存储,例如LocalStorage或SessionStorage中,并在每次请求中将JWT添加到请求头中。在一些安全性要求较高的场景中,客户端还可以使用HTTPOnly Cookie来保存JWT。 总之,ASP.NET Core提供了丰富的工具和中间件来简化JWT登录校验的实现,并且可以很好地与前后端分离的架构进行集成,让开发者可以便捷地实现用户身份验证和授权功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值