首页
学习
活动
专区
圈层
工具
发布

使用Angular和spring进行Jwt身份验证

Angular与Spring JWT身份验证详解

基础概念

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为JSON对象。它由三部分组成:

  • Header(头部):包含令牌类型和使用的哈希算法
  • Payload(负载):包含声明(claims),即用户信息和其他数据
  • Signature(签名):用于验证消息在传输过程中没有被篡改

优势

  1. 无状态性:服务器不需要存储会话信息
  2. 跨域支持:适合分布式系统和微服务架构
  3. 安全性:基于数字签名,防止篡改
  4. 灵活性:可以包含自定义声明
  5. 可扩展性:适用于移动应用和单页应用(SPA)

实现方案

后端(Spring Boot)实现

  1. 添加依赖到pom.xml
代码语言:txt
复制
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
  1. 创建JWT工具类:
代码语言:txt
复制
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Component
public class JwtTokenUtil {
    private static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60; // 5小时
    private final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
                .signWith(key)
                .compact();
    }

    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }

    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
}
  1. 创建JWT过滤器:
代码语言:txt
复制
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtRequestFilter extends OncePerRequestFilter {
    private final UserDetailsService userDetailsService;
    private final JwtTokenUtil jwtTokenUtil;

    public JwtRequestFilter(UserDetailsService userDetailsService, JwtTokenUtil jwtTokenUtil) {
        this.userDetailsService = userDetailsService;
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String requestTokenHeader = request.getHeader("Authorization");

        String username = null;
        String jwtToken = null;

        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                logger.warn("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                logger.warn("JWT Token has expired");
            }
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken authenticationToken = 
                    new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(
                    new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}
  1. 配置Spring Security:
代码语言:txt
复制
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final UserDetailsService userDetailsService;
    private final JwtRequestFilter jwtRequestFilter;

    public SecurityConfig(UserDetailsService userDetailsService, JwtRequestFilter jwtRequestFilter) {
        this.userDetailsService = userDetailsService;
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authenticate", "/register").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
  1. 创建认证控制器:
代码语言:txt
复制
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthenticationController {
    private final AuthenticationManager authenticationManager;
    private final UserDetailsService userDetailsService;
    private final JwtTokenUtil jwtTokenUtil;

    public AuthenticationController(AuthenticationManager authenticationManager, 
                                   UserDetailsService userDetailsService, 
                                   JwtTokenUtil jwtTokenUtil) {
        this.authenticationManager = authenticationManager;
        this.userDetailsService = userDetailsService;
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @PostMapping("/authenticate")
    public String createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) {
        authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                authenticationRequest.getUsername(), 
                authenticationRequest.getPassword()
            )
        );

        final UserDetails userDetails = userDetailsService.loadUserByUsername(
            authenticationRequest.getUsername()
        );

        return jwtTokenUtil.generateToken(userDetails);
    }
}

前端(Angular)实现

  1. 创建认证服务:
代码语言:txt
复制
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private readonly JWT_TOKEN = 'JWT_TOKEN';
  private loggedIn = new BehaviorSubject<boolean>(false);

  constructor(private http: HttpClient, private router: Router) {
    this.loggedIn.next(this.isLoggedIn());
  }

  login(username: string, password: string): Observable<any> {
    return this.http.post<any>('/api/authenticate', {username, password}).pipe(
      tap(response => {
        this.doLoginUser(username, response.token);
      })
    );
  }

  private doLoginUser(username: string, token: string) {
    this.storeToken(token);
    this.loggedIn.next(true);
  }

  logout() {
    this.removeToken();
    this.loggedIn.next(false);
    this.router.navigate(['/login']);
  }

  isLoggedIn(): boolean {
    return !!this.getToken();
  }

  getToken(): string | null {
    return localStorage.getItem(this.JWT_TOKEN);
  }

  private storeToken(token: string) {
    localStorage.setItem(this.JWT_TOKEN, token);
  }

  private removeToken() {
    localStorage.removeItem(this.JWT_TOKEN);
  }
}
  1. 创建HTTP拦截器:
代码语言:txt
复制
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
  constructor(private authService: AuthService) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const token = this.authService.getToken();
    if (token) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    }
    return next.handle(request);
  }
}
  1. 在AppModule中注册拦截器:
代码语言:txt
复制
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { JwtInterceptor } from './services/jwt.interceptor';

@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }
  ]
})
export class AppModule { }
  1. 创建登录组件:
代码语言:txt
复制
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AuthService } from '../services/auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
  loginForm: FormGroup;
  error = '';

  constructor(
    private formBuilder: FormBuilder,
    private authService: AuthService,
    private router: Router
  ) {
    this.loginForm = this.formBuilder.group({
      username: ['', Validators.required],
      password: ['', Validators.required]
    });
  }

  onSubmit() {
    if (this.loginForm.invalid) {
      return;
    }

    const { username, password } = this.loginForm.value;
    this.authService.login(username, password).subscribe(
      () => {
        this.router.navigate(['/dashboard']);
      },
      error => {
        this.error = error.error.message || 'Login failed';
      }
    );
  }
}

常见问题及解决方案

1. JWT令牌过期问题

问题现象:用户操作时突然被登出,需要重新登录

原因:JWT令牌设置了有效期,过期后无法继续使用

解决方案

  • 实现令牌刷新机制,当令牌快过期时自动获取新令牌
  • 前端可以监听401错误,自动跳转到登录页

2. 跨域问题

问题现象:前端请求时出现CORS错误

原因:前后端分离部署时,域名或端口不同导致跨域

解决方案

  • 后端配置CORS支持:
代码语言:txt
复制
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowedHeaders("*")
            .exposedHeaders("Authorization")
            .allowCredentials(true);
    }
}

3. 安全性问题

问题现象:令牌被窃取导致安全问题

原因:JWT存储在localStorage中容易被XSS攻击获取

解决方案

  • 使用HttpOnly和Secure的Cookie存储令牌
  • 实现短有效期+刷新令牌机制
  • 添加IP检查等额外验证

4. 性能问题

问题现象:每次请求都需要解析JWT,影响性能

原因:JWT签名验证需要计算资源

解决方案

  • 使用更高效的算法如HS256
  • 实现令牌缓存机制
  • 对于频繁访问的API可以考虑短期缓存认证结果

应用场景

  1. 单页应用(SPA)认证:Angular等前端框架构建的应用
  2. 移动应用后端:为iOS/Android应用提供认证服务
  3. 微服务架构:服务间安全通信
  4. 第三方API访问:为合作伙伴提供API访问权限
  5. 无服务器架构:与云函数等无服务器服务集成

通过上述实现,您可以构建一个完整的基于Angular和Spring的JWT身份验证系统,既安全又易于维护。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

使用Spring Security和JWT来进行身份验证和授权(三)

实现身份验证和授权接下来,我们需要实现基于JWT的身份验证和授权。...该类从数据库中获取用户信息,并将其转换为Spring Security用户详细信息对象。接下来,我们需要实现JWT身份验证入口点。...该类用于过滤所有请求,并验证JWT令牌。如果JWT令牌有效,则设置Spring Security上下文的身份验证信息。现在我们需要将这些组件集成到我们的Spring Boot应用程序中。...我们要求对所有其他请求进行身份验证。我们配置了JWT身份验证入口点(jwtAuthenticationEntryPoint)和JWT请求过滤器(jwtRequestFilter)。...我们配置了会话管理策略为“STATELESS”,这意味着我们将不使用HTTP会话进行身份验证和授权。我们将JWT请求过滤器添加到Spring Security的过滤器链中。

2.3K40
  • Spring Boot 使用 JWT 进行身份和权限验证

    上周写了一个 适合初学者入门 Spring Security With JWT 的 Demo,这篇文章主要是对代码中涉及到的比较重要的知识点的说明。...适合初学者入门 Spring Security With JWT 的 Demo 这篇文章中说到了要在十一假期期间对代码进行讲解说明,但是,你们懂得,到了十一就一拖再拖,眼看着今天就是十一的尾声了,抽了一下午完成了这部分内容...Demo 地址:https://github.com/Snailclimb/spring-security-jwt-guide 。...第一个过滤器主要用于根据用户的用户名和密码进行登录验证(用户请求中必须有用户名和密码这两个参数),它继承了 UsernamePasswordAuthenticationFilter 并且重写了下面三个方法...当用户使用系统返回的 token 信息进行登录的时候 ,会首先经过doFilterInternal()方法,这个方法会从请求的 Header 中取出 token 信息,然后判断 token 信息是否为空以及

    3.9K70

    怎么使用slim-jwt-auth对API进行身份验证

    这两天一直想找个机会做一下API的身份验证,就像微博那样提供接口给别人用,但又有所限制,也不会导致接口滥用。...现在正好可以用之前写的成绩查询接口来做这个身份验证的实验。 准备工作 在做一个二维码签到/点名系统时,需要后台同时支持移动端、PC端和网页版,因此决定写成接口,这样比较方便。...安装框架和用到的第三方组件 官方推荐使用composer进行安装,下面不说废话了,Come on Install composer Slim and some third plugins curl...) 假定使用我们的接口的人(以下称”客户”)已经注册成为会员,已经拥有获取接口使用权限的”username” 和 “password” 客户向后台发送附带”username” 和 “password...” 和 “key” 的请求, 请求获取接口使用权的”accecc_token” 客户拿到”accecc_token”后, 向成绩查询接口发起请求同时附带”access_token”和”key” 后台验证并返回相应的结果

    2.4K20

    在 .NET 89 中使用 AppUser 进行 JWT 令牌身份验证

    JWT 身份验证是保护 API 的标准方法之一。这允许无状态身份验证,因为签名令牌是在客户端和服务器之间传递的。在 .NET 8 中,使用 JWT 令牌的方式得到了改进。...此信息是经过数字签名的,因此可以验证和信任。可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对对 JWT 进行签名。...受众:指定令牌的目标受众(通常是使用 API 的客户端或服务)。 ❗️密钥:密钥用于对 JWT 进行签名,以确保其真实性。它应该是一个长而随机的字符串,以防止篡改。...appsettings.json ❗️IssuerSigningKey:使用对称安全密钥对 JWT 进行签名和验证,将配置中的密钥转换为字节数组进行加密。...jwt 令牌 获取天气预报返回结果 获取用户电子邮件 返回用户电子邮件 在本文中,我们演示了如何在 .NET 8 中使用最小 API 结构实现 JWT 令牌身份验证。

    1.2K10

    虾皮二面:什么是 JWT? 如何基于 JWT 进行身份验证?

    分享一下群友面试虾皮遇到的关于 JWT 的面试真题。 相关面试题如下: 什么是 JWT?为什么要用 JWT? JWT 由哪些部分组成? 如何基于 JWT 进行身份验证?...并且, 使用 Token 认证可以有效避免 CSRF 攻击,因为 Token 一般是存在在 localStorage 中,使用 JWT 进行身份验证的过程中是不会涉及到 Cookie 的。...我在 JWT 优缺点分析[1]这篇文章中有详细介绍到使用 JWT 做身份认证的优势和劣势。 下面是 RFC 7519[2] 对 JWT 做的较为正式的定义。...如何基于 JWT 进行身份验证?...在基于 Token 进行身份验证的的应用程序中,服务器通过 Payload、Header 和 Secret(密钥)创建Token(令牌)并将 Token 发送给客户端。

    1.3K31

    深度解析 Spring Security:身份验证、授权、OAuth2 和 JWT 身份验证的完整指南

    Spring Security 提供了广泛的选项来实现身份验证,包括支持传统的用户名/密码身份验证,以及更现代的替代方案,例如 OAuth 和 JSON Web Tokens(JWT)。...JWT身份验证 Spring Security 可以用于对 API 实现 JWT 身份验证和授权。该库提供了一个基于 JWT 的身份验证过滤器,您可以将其添加到 API 终点。...该过滤器将检查请求头中包含的 JWT,如果有效,则会在安全上下文中设置身份验证信息。然后,您可以使用安全上下文对 API 终点执行授权检查。...它通过减少样板配置代码来节省开发人员的时间,并且可以通过属性和注释进行微调,以提供对自动配置的细粒度控制。...可以使用各种选项和属性来保护、限制速率和自定义执行器端点。 Spring Boot 执行器通常用于生产环境中,以监视应用程序的健康和性能,并识别可能出现的任何问题。

    87910

    使用Angular CLI进行Build (构建) 和 Serve

    Build主要会做以下动作: 编译项目文件并输出到某个目录 Build targets决定了输出的结果 bundling 打包 生产环境的build还会进行uglify和tree-shaking(把没用的代码去掉...和第三方库 可以使用source-map-explorer来分析依赖, 并且查看哪些模块和类在bundle里面....下面使用source-map-explorer进行分析, 首先安装它: npm install --save-dev source-map-explorer 然后执行 ng build, 再执行: ....执行aot会去掉一些程序执行不需要的代码, 例如angular的compiler这时就不在build输出的文件里了(可以使用source-map-explorer查看)....为项目生成webpack配置和脚本. 执行该命令试试: ? 看看有哪些变化: .angular-cli.json: ? package.json: ? 命令脚本都变了 ?

    2.7K70

    如何使用MyJWT对JWT进行破解和漏洞测试

    MyJWT MyJWT是一款功能强大的命令行工具,MyJWT专为渗透测试人员、CTF参赛人员和编程开发人员设计,可以帮助我们对JSON Web Token(JWT)进行修改、签名、注入、破解和安全测试等等...功能介绍 将新的JWT拷贝至剪贴板; 用户接口; 带颜色高亮输出; 修改JWT(Header/Payload); 安全性高; RSA/HMAC混淆; 使用密钥对JWT进行签名; 通过暴力破解以猜测密钥;...-h, —add-header key=value user=admin 向JWT Header中添加一个新密钥和值,如果密钥已存在,则会替换旧的密钥值。...-p, —add-payload key=value user=admin 向JWT Payload添加一个新的密钥和值,如果密钥已存在,则会替换旧的密钥值。...-m, —method text POST 指定发送JWT所使用的请求方法。

    3.7K10

    【ASP.NET Core 基础知识】--身份验证和授权--使用Identity进行身份验证

    Password Hasher(密码哈希器):用于对用户密码进行哈希和验证。Identity框架使用哈希算法对密码进行加密,提高安全性。...通过少量的配置,你就可以将身份验证和授权功能添加到你的应用中。 可定制性: 尽管 Identity 提供了默认的实现,但你可以根据应用程序的需求进行定制。...社交登录集成: Identity 支持与外部身份提供者(如Google、Facebook、Microsoft等)集成,使用户能够使用他们的社交媒体账户进行登录。...以下是一些可能的挑战: 定制复杂性: 在实施一些特定或复杂的身份验证和授权需求时,可能需要深入了解 Identity 框架的内部工作机制,并进行一些额外的定制。...在更新到新版本时,你可能需要进行一些调整以保持兼容性。 文档理解: 由于 Identity 框架提供了丰富的功能,理解和正确使用这些功能可能需要详细阅读文档和参考资料。

    2.4K00

    一个全栈SpringBoot项目-Book Social Network

    后端是使用 Spring Boot 3 和 Spring Security 6 构建的,而前端是使用 Angular 和 Bootstrap 进行样式开发的。...电子邮件验证:使用安全电子邮件验证码激活帐户。 用户身份验证:现有用户可以安全地登录其帐户。 图书管理:用户可以创建、更新、共享和归档他们的图书。 图书借阅:实施必要的检查以确定图书是否可以借阅。...Bootstrap 学习目标 通过完成这个项目,学生将学习: 根据业务需求设计类图 实施单一回购方法 使用 JWT 令牌和 Spring Security 保护应用程序 通过电子邮件注册用户并验证帐户...通过 Spring Data JPA 使用继承 实现服务层并处理应用程序异常 使用 JSR-303 和 Spring Validation 进行对象验证 处理自定义异常 实施分页和 REST API...最佳实践 使用 Spring Profiles 进行特定于环境的配置 使用 OpenAPI 和 Swagger UI 记录 API 落实业务需求并处理业务异常 Docker 化基础设施 CI/CD 管道和部署

    28700

    PHP怎样使用JWT进行授权验证?

    本文目录 概述 JWT的原理是什么? 怎样使用JWT? 客户端怎样回传JWT? 使用JWT要注意什么?...1.概述 JWT可以取代以往的基于 COOKIE/SESSION 的鉴权体系,是目前最热门跨域鉴权的解决方案,接下来从 JWT 的原理,到 PHP 示例代码,简单说明业务怎样使用 JWT 进行授权验证。...HS256加密 :生成与验证JWT 使用 HS256 算法生成 JWT,这是一种对称加密,使用同一个密钥串进行加密和解密。...JWT 官网的标准是将 JWT 凭证放在 HTTP 报文 头部的 Authorization 中进行请求,如向服务器请求 用户的 个人信息,HTTP报文 如下示例 GET https://api.example.com...为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证(如通过手机 验证码 再次验证,或者再次输入用户密码进行验证)。

    3.9K11

    如何使用GPG密钥进行SSH身份验证

    输入您的全名,电子邮件地址和评论(如果需要)。选择O'好'。 在仔细查看特工后,输入一个长而安全的密码短语,用于加密本地存储中的密钥。在计算机生成密钥对的同时,将其写入您知道的物理安全的地方。...要使用SSH进行身份验证,我们需要生成第二个用于身份验证的子项。...每次要访问GPG密钥时都需要此PIN(例如,每次使用SSH进行身份验证时),并且限制为8个字符。 通过选择更改管理员PIN 3 - change Admin PIN。...此PIN是进行管理更改所必需的,如步骤2中所示,并且限制为6个字符。为了获得最佳安全性,请勿将此PIN存储在数字位置,因为日常使用YubiKey不需要。 通过选择Q然后键入退出这些菜单quit。...提供您的GPG密钥而不是SSH密钥 在本节中,我们将配置您的本地计算机,以便GPG和SSH之间的连接正常工作。 返回本地计算机,导入所有相应的GPG密钥并插入相应的GPG设备。

    9.5K30

    Koa2 使用 JWT 进行鉴权

    在前后端分离的开发中,通过 Restful API 进行数据交互时,如果没有对 API 进行保护,那么别人就可以很容易地获取并调用这些 API 进行操作。...Json Web Token 简称为 JWT,它定义了一种用于简洁、自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。...JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名。...首先用户登录时,输入用户名和密码后请求服务器登录接口,服务器验证用户名密码正确后,生成token并返回给前端,前端存储token,并在后面的请求中把token带在请求头中传给服务器,服务器验证token...既然服务器端使用 Koa2 框架进行开发,除了要使用到 jsonwebtoken 库之外,还要使用一个 koa-jwt 中间件,该中间件针对 Koa 对 jsonwebtoken 进行了封装,使用起来更加方便

    34210
    领券