惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
Arctic Wolf
Know Your Adversary
Know Your Adversary
T
Tor Project blog
C
Cisco Blogs
G
GRAHAM CLULEY
S
Schneier on Security
AWS News Blog
AWS News Blog
Scott Helme
Scott Helme
C
Cybersecurity and Infrastructure Security Agency CISA
雷峰网
雷峰网
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
S
SegmentFault 最新的问题
S
Security Affairs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
J
Java Code Geeks
美团技术团队
Hacker News - Newest:
Hacker News - Newest: "LLM"
U
Unit 42
Latest news
Latest news
T
Tailwind CSS Blog
GbyAI
GbyAI
月光博客
月光博客
PCI Perspectives
PCI Perspectives
Attack and Defense Labs
Attack and Defense Labs
Forbes - Security
Forbes - Security
S
Securelist
AI
AI
Recent Announcements
Recent Announcements
C
Check Point Blog
I
Intezer
宝玉的分享
宝玉的分享
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
NISL@THU
NISL@THU
Hacker News: Ask HN
Hacker News: Ask HN
O
OpenAI News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Project Zero
Project Zero
V2EX - 技术
V2EX - 技术
Y
Y Combinator Blog
博客园 - 【当耐特】
aimingoo的专栏
aimingoo的专栏
F
Full Disclosure
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News

博客园 - oec2003

读《有效需求分析》 重读《打造 Facebook》 dotNet Core 3.1 使用 Aspose (部署 Docker) 为什么这么忙,还依然做不好事情? dotNET Core:编码规范 程序员是终身学习的职业,应该怎么学习? 一款用了就不想走的工具 dotNET:怎样处理程序中的异常(实战篇)? dotNET:怎样处理程序中的异常(理论篇)? Nginx:rewrite 的几个技巧 如何激发团队潜能? dotNET Core 3.X 使用 Autofac 来增强依赖注入 dotNET Core 3.X 依赖注入 读《鞋狗》 Jenkins 中以构建 Tag 来实现版本管理 dotNET Core 3.X 请求处理管道和中间件 dotNET Core 3.X 使用 Web API 程序员还有35岁的坎吗? 远程办公也可以高效
dotNET Core 3.X 使用 Jwt 实现接口认证
oec2003 · 2020-04-20 · via 博客园 - oec2003

在前后端分离的架构中,前端需要通过 API 接口的方式获取数据,但 API 是无状态的,没有办法知道每次请求的身份,也就没有办法做权限的控制。如果不做控制,API 就对任何人敞开了大门,只要拿到了接口地址就可以进行调用,这是非常危险的。本文主要介绍下在 dotNET Core Web API 中使用 Jwt 来实现接口的认证。

Jwt 简介

Jwt 的全称是 JSON Web Token,是目前比较流行的接口认证解决方案。有了 Jwt 后,从客户端请求接口的流程如下图:

  • 客户端发送用户名密码信息到认证服务器获取 token;
  • 客户端请求 API 获取数据时带上 token;
  • 服务器端验证 token,合法则返回正确的数据。

有一个网站叫:https://jwt.io/ ,我们在这个站点上对 Jwt 产生的 token 做验证:

从上图可以看出 Jwt 生产的 token 由三个部分组成:

  • Header(红色):头
  • Playload(紫色):负载
  • Verify Sigantuer(蓝色):签名

这三个部分由英文的点进行分隔开

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoib2VjMjAwMyIsInNpdGUiOiJodHRwOi8vZndoeXkuY29tIiwiaWF0IjoxNTE2MjM5MDIyfQ.DYgo4eEUwlYJqQoLvAuFPxFRVcCow77Zyl2byaK6Uxk

头信息是一个 Json 格式的数据

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg:表示加密的算法
  • typ:表示 token 的类型

Playload

Playload 是 token 的主体内容部分,我们可以用来传递一些信息给客户端,比如过期时间就是通过 Playload 来进行传递的。 但因为默认情况下 Playload 的数据是明文的,所以敏感信息不要放在这里。

Verify Sigantuer

Verify Sigantuer 是对前面两个部分的签名,防止数据篡改。

使用 Jwt

下面一步步介绍在 dotNET Core Web API 项目中使用 Jwt:

添加 Jwt 的包引用

在 Web API 项目中添加对 Microsoft.AspNetCore.Authentication.JwtBearer 包的引用

修改 Starup

1、在 ConfigureServices 方法中添加服务注册。

// jwt 认证
JwtSettings jwtSettings = new JwtSettings();
services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));
Configuration.GetSection("JwtSettings").Bind(jwtSettings);
    
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o=>
    {
        o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
        {
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtSettings.Issuer,
            ValidAudience = jwtSettings.Audience,
            //用于签名验证
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.SecretKey)),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

JwtSettings 的配置设置在 appsettings.json 配置文件中:

2、在 Configure 方法中添加对中间件的使用。

app.UseAuthentication();
app.UseAuthorization();

添加认证接口

添加 AuthorizeController 控制器:

[ApiController]
public class AuthorizeController: BaseController
{
    private readonly IUserService _userService;
    private readonly JwtSettings _jwtSettings;

    public AuthorizeController(IMapper mapper,
        IUserService userService,
        IOptions<JwtSettings> options) : base(mapper)
    {
        _userService = userService;
        _jwtSettings = options.Value;
    }

    /// <summary>
    ///  获取 token
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    [HttpPost]
    public string Token(TokenDto request)
    {
        bool isValidate = _userService.ValidatePassword(request.UserName, request.Password);

        if(!isValidate) return string.Empty;
        
        var claims = new Claim[]{
            new Claim(ClaimTypes.Name,request.UserName)
        };
        
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        
        var token = new JwtSecurityToken(_jwtSettings.Issuer,
            _jwtSettings.Audience,
            claims,
            DateTime.Now,
            DateTime.Now.AddSeconds(10),
            creds);
        
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

上面代码中使用 IOptions 来做强类型配置,将 JwtSettings 配置类注入到该控制器中使用,关于更多配置内容可以参考:《dotNET Core 配置》。

使用 Postman 测试

1、在需要进行认证的控制器或接口方法上添加 [Authorize] 标记。

2、调用接口 http://localhost:5000/api/Authorize/token 获取 token。

3、在请求接口时使用 Authorization 的方式使用 token,token 的类型为 Bearer Token ,可以看到带上 token 后,数据正常返回。

在 Vue 中调用

前端技术有很多种,在这里以 Vue 为例,Vue 中处理 Jwt 有以下几个步骤:

1、请求接口时判断 localStorage 中是否有 token 数据,没有 token 数据或者 token 已经过期,需要重新调用接口获取新的 token;
2、使用 axios 的拦截器,在所有请求的 Header 中都添加 Authorization。

示例代码:

希望本文对您有所帮助。