当前位置: 首页 > news >正文

微服务-微服务Spring Security OAuth 2实战

1. Spring Authorization Server 是什么

Spring Authorization Server 是一个框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产品提供了一个安全、轻量级和可定制的基础。说白了,Spring Authorization Server 就是一个认证(授权)服务器。

官方主页:Spring Authorization Server

2. 为什么有 Spring Authorization Server

因为随着网络和设备的发展,原先的 OAuth 2.0 已经不能满足现今的需求了,OAuth 社区对 OAuth 2.0 中的几种授权模式进行了取舍和优化,并增加一些新的特性, 于是推出了 OAuth 2.1,而原先的 Spring Security OAuth 2.0 使用的是 OAuth 2.0 协议,为满足新的变化,Spring Security 团队重新写了一套叫 Spring Authorization Server 的认证授权框架来替换原先的 Spring Security OAuth 2.0。从官网中可以看到,原先的 Spring Security OAuth 2.0 已从 Spring Security 目录下被移除,接着是多出 Spring Authorization Server 作为单独项目。

Springboot2.x Oauth2实现:

  • Spring Security Oauth2 支持搭建授权服务器和资源服务器
  • 课程:27-微服务安全Spring Security OAuth2实战一

Springboot3.x Oauth2实现:

  • Spring Security6 自身提供资源和客户端类库支持
  • Spring Authorization Server支持授权服务器搭建

3. OAuth2.0协议介绍

OAuth 2.0 (Open Authorization)是一种开放标准的授权协议,允许用户授权第三方应用访问其在某个服务提供者上的受保护资源,而无需将其实际的凭证(如用户名和密码)分享给第三方应用。这种方式可以增加安全性,同时允许用户更好地控制其数据的访问权限。

OAuth2.0协议:RFC 6749 - The OAuth 2.0 Authorization Framework

3.1 角色

  • 客户端(client):使用授权服务器作为认证渠道的平台,一般指的是第三方应用。例如,微信提供 OAuth 2.0 认证平台,我们的 APP 支持微信登录,那么我们的 APP 对于微信服务来说就是客户端。又例如,我们是政府某一平台的服务,我们平台维护的数据代表着足够高的权威,那么其他政府部门或合作方,需要从我们的平台中查询数据,或者利用我们平台的认证进行登录,那么其他部门或合作方的应用就是客户端。
  • 资源服务器(resource server):简单的说,就是提供接口给客户端访问的服务器,访问资源服务器上受保护的接口,则需要带上令牌(token)。例如分布式微服务中的用户服务、订单服务等部署的服务器都属于资源服务器。
  • 资源所有者(resource owner):拥有该资源的主体对象,一般指用户。客户端向资源服务器请求获取用户数据时,资源所有者参与确认授权或拒绝操作。
  • 授权服务器(authorization server):对客户端和用户进行身份认证、授权的服务器,认证授权成功,则颁发令牌(token)。

3.2 OAuth2.0协议的运行流程

OAuth 2.0的运行流程如下图,摘自RFC 6749:

(A)用户打开客户端以后,客户端要求用户给予授权。

(B)用户同意给予客户端授权。

(C)客户端使用上一步获得的授权,向授权服务器申请令牌。

(D)授权服务器对客户端进行认证以后,确认无误,同意发放令牌。

(E)客户端使用令牌,向资源服务器申请获取资源。

(F)资源服务器确认令牌无误,同意向客户端开放资源。

令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。

(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。

(2)令牌可以被数据所有者撤销,会立即失效。密码一般不允许被他人撤销。

(3)令牌有权限范围(scope)。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。

上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。

3.3 应用场景

OAuth 2.0 在许多不同的应用场景中都能够发挥作用,尤其是那些涉及到第三方应用程序访问用户数据或资源的情况。以下是一些常见的 OAuth 2.0 应用场景:

  • 社交媒体登录:许多网站和应用程序允许用户使用其社交媒体账户(如Facebook、Google、Twitter等)进行登录。OAuth 2.0 可以用于授权第三方应用访问用户的社交媒体数据,如好友列表、社交活动等。
  • 第三方应用集成:用户可能使用多个不同的应用和服务,例如电子邮件、日历、云存储等。OAuth 2.0 可以用于实现单一的登录授权,使用户能够在多个应用之间共享数据,而无需在每个应用中都输入凭证。
  • 移动应用访问 API:移动应用可能需要访问后端服务器上的受保护资源,例如用户数据或其他服务。OAuth 2.0 可以确保安全地进行授权和访问控制,同时减少对用户凭证的需求。
  • 授权访问云服务:当用户需要将他们的数据存储在云服务(如Google Drive、Dropbox)中时,OAuth 2.0 可以确保这些服务只能以授权的方式访问用户的数据。
  • API 访问控制:企业和开发者可以使用 OAuth 2.0 来实现对其 API 的访问控制。只有经过授权的应用程序才能访问和使用这些 API。
  • 联合身份验证:在不同的身份提供者之间实现联合身份验证,使用户可以使用一个身份提供者的凭证来访问另一个身份提供者的资源。
  • 医疗保健应用:在医疗保健领域,患者的健康数据可能由多个医疗应用和机构共享。OAuth 2.0 可以用于确保授权的数据访问,同时保护患者隐私。
  • IoT 设备访问:物联网设备可能需要访问云服务或其他资源。OAuth 2.0 可以用于在 IoT 设备和云之间实现安全的授权流程。

这些只是 OAuth 2.0 可能应用的一些例子。基本上,任何需要实现安全的第三方应用程序访问用户数据或资源的情况下,OAuth 2.0 都可能是一个合适的解决方案。

3.4 授权模式详解

        授权码模式:应用最广泛,适合web应用/app/前端

        资源所有者密码模式:官方应用

        客户端凭证模式:适合无用户参与的应用

        刷新令牌模式:适合令牌访问过期后刷新令牌

客户端模式

        客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行授权。客户端模式是安全级别最低而且要求授权服务器对客户高度信任的模式,因为客户端向授权服务器请求认证授权的过程中,至始至终都没有用户的参与,未经过用户允许,客户端凭提供自己在授权服务器注册的信息即可在授权服务器完成认证授权,而客户端获得认证授权以后,则拥有从资源服务器操作用户数据的权限,这种模式一般应用于公司内部系统或者有着高度保密责任的合作伙伴之间的对接。

它的步骤如下:

(A)客户端向授权服务器进行身份认证,并要求一个访问令牌。

(B)授权服务器确认无误后,向客户端提供访问令牌。

客户端模式的时序图如下:

1:客户端首先在认证服务器注册好客户端信息。

2:认证服务器存储维护客户端信息。

3:客户端带上 client_id、client_secret、grant_type(写死client_credentials)等参数向认证服务器发起获取 token 请求。

4:认证服务器校验客户端信息,校验通过,则发放令牌(access_token),校验失败,则返回异常信息。

5:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。

实现效果

1. A 应用在命令行向 B 发出请求。

> https://oauth.b.com/token?
>   grant_type=client_credentials&
>   client_id=CLIENT_ID&
>   client_secret=CLIENT_SECRET

2. B 网站验证通过以后,直接返回令牌。

密码模式

如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码模式"(password)。

密码模式是一种安全级别较低而且要求资源拥有者(用户)完全信任客户端的模式,该模式可以理解为在客户端模式的基础上增加了对用户的账号、密码在认证服务器进行校验的操作,是客户端代理用户的操作。在 OAuth 2.1 中,密码模式已经被废除,在第三方平台上,使用密码模式,对于用户来说是一种非常不安全的行为,假设某平台客户端支持 QQ 登录,用户使用自己 QQ 的账号、密码在该平台上输入进行登录,则该平台将拥有用户 QQ 的账号、密码,对于用户来说,将自己 QQ 的账号、密码提供给第三方平台,这种行为是非常不安全的。

密码模式一般适合应用在自己公司内部使用的系统和自己公司的 app 产品,例如一些 ERP、CRM、WMS 系统,因为都是自己公司的产品,这种情况下就不存在用户提供账号、密码给第三方客户端进行代理登录的情形了。

它的步骤如下:

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给授权服务器,向后者请求令牌。

(C)授权服务器确认无误后,向客户端提供访问令牌。

密码模式的时序图如下:

1:客户端首先在认证服务器注册好客户端信息。

2:认证服务器存储维护客户端信息。

3:用户提供认证平台的账号、密码给客户端(这里的客户端可以是浏览器、APP、第三方应用的服务器)。

4:客户端带上 client_id、client_secret、grant_type(写死password)、username、password 等参数向认证服务器发起获取 token 请求。

5:认证服务器校验客户端信息,校验失败,则返回异常信息,校验通过,则往下继续校验用户验账号、密码。

6:认证服务器校验用户账号、密码,校验通过,则发放令牌(access_token),校验失败,则返回异常信息。

7:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。

实现效果

> https://oauth.b.com/token?
>   grant_type=password&       # 授权方式是"密码模式"
>   username=USERNAME&
>   password=PASSWORD&
>   client_id=CLIENT_ID
>   client_secret=client_secret

 

2. B 网站验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 因此拿到令牌。

授权码模式

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该授权码获取令牌。

授权码模式是 OAuth 2.0 协议中安全级别最高的一种认证模式,他与密码模式一样,都需要使用到用户的账号信息在认证平台的登录操作,但有所不同的是,密码模式是要求用户直接将自己在认证平台的账号、密码提供给第三方应用(客户端),由第三方平台进行代理用户在认证平台的登录操作;而授权码模式则是用户在认证平台提供的界面进行登录,然后通过用户确认授权后才将一次性授权码提供给第三方应用,第三方应用拿到一次性授权码以后才去认证平台获取 token。

适用场景:目前市面上主流的第三方验证都是采用这种模式

它的步骤如下:

(A)用户访问客户端,后者将前者导向授权服务器。

(B)用户选择是否给予客户端授权。

(C)假设用户给予授权,授权服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。

(D)客户端收到授权码,附上早先的"重定向URI",向授权服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

(E)授权服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

授权码模式的时序图如下:

1:客户端首先在认证服务器注册好客户端信息。

2:认证服务器存储维护客户端信息。

3:用户在客户端上发起登录。

4:向认证服务器发起认证授权请求,例如http://localhost:9000/auth/oauth/authorize?client_id=xxx&response_type=code&scope=message.read&redirect_uri=http://www.baidu.com,注意,此时参数不需要client_secret。

5:认证服务器带上客户端参数,将操作引导至用户授权确认页面,用户在该页面进行授权确认操作。

6:用户在授权页面选择授权范围,点击确认提交,则带上客户端参数和用户授权范围向认证服务器获取授权码。注意,此处操作已经脱离了客户端。

7:认证服务器校验客户端信息和授权范围(因为客户端在认证平台注册的时候,注册信息包含授权范围,如果用户选择的授权范围不在注册信息包含的范围内,则将因权限不足返回失败)。

8:校验通过,将授权码拼接到客户端注册的回调地址返回给客户端。

9:客户端拿到认证服务器返回的授权码后,带上客户端信息和授权码向认证服务器换取令牌(access_token)。

10:认证服务器校验授权码是否有效,如果有效,则返回令牌(access_token);如果无效,则返回异常信息。

11:客户端成功获取到令牌(access_token)后,就可以带着令牌去访问资源服务器了。

实现效果

1. A网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。

> https://b.com/oauth/authorize?
> response_type=code& #要求返回授权码(code)
> client_id=CLIENT_ID& #让 B 知道是谁在请求 
> redirect_uri=CALLBACK_URL& #B 接受或拒绝请求后的跳转网址
> scope=read # 要求的授权范围(这里是只读) 
>
客户端申请授权的 URI ,包含以下参数:
        response_type:表示授权类型,必选项,此处的值固定为 "code"
        client_id:表示客户端的 ID ,必选项
        redirect_uri:表示重定向 URI ,可选项
        scope:表示申请的权限范围,可选项
        state:表示客户端的当前状态,可以指定任意值,授权服务器会原封不动地返回这个值。
2. 用户跳转后, B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回redirect_uri 参数指定的网址。跳转时,会传回一个授权码,就像下面这样。
> https://a.com/callback?code=AUTHORIZATION_CODE #code参数就是授权码
>
3. A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。 用户不可见,服务端行为
 > https://b.com/oauth/token?
> client_id=CLIENT_ID&
> client_secret=CLIENT_SECRET& # client_id和client_secret用来让 B 确认 A 的身
份,client_secret参数是保密的,因此只能在后端发请求> grant_type=authorization_code& # 采用的授权方式是授权码
> code=AUTHORIZATION_CODE& # 上一步拿到的授权码
> redirect_uri=CALLBACK_URL # 令牌颁发后的回调网址 
>
4. B 网站收到请求以后,就会颁发令牌。具体做法是向 redirect_uri 指定的网址,发送一段 JSON 数据。
{ "access_token":"ACCESS_TOKEN", # 令牌
"token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{...}}
简化模式
        简化模式(也叫隐式模式)是相对于授权码模式而言的,对授权码模式的交互做了一下简化,省去了 客户端使用授权码去认证服务器换取令牌(access_token)的操作,即用户在代理页面选择授权范围 提交授权确认后,认证服务器通过客户端注册的回调地址直接就给客户端返回令牌(access_token )了。
        这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌 的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
它的步骤如下:
(A)客户端将用户导向授权服务器。
B )用户决定是否给于客户端授权。
C )假设用户给予授权,授权服务器将用户导向客户端指定的 " 重定向 URI" ,并在 URI Hash 部分包 含了访问令牌。
D )浏览器向资源服务器发出请求,其中不包括上一步收到的 Hash 值。
E )资源服务器返回一个网页,其中包含的代码可以获取 Hash 值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
G )浏览器将令牌发给客户端。
简化模式时序图如下:
1 :客户端首先在认证服务器注册好客户端信息。
2 :认证服务器存储维护客户端信息。
3 :用户在客户端上发起登录。
4 :向认证服务器发起认证授权请求,例如 http://localhost:9000/auth/oauth/authorize?client_id=xxx&re
sponse_type=token&scope=message.read&redirect_uri=http://www.baidu.com ,注意,此时参数不需 要 client_secret
5 :认证服务器带上客户端参数,将操作引导至用户授权确认页面,用户在该页面进行授权确认操作。
6 :用户在授权页面选择授权范围,点击确认提交,则带上客户端参数和用户授权范围向认证服务器获 取令牌(access_token

相关文章:

微服务-微服务Spring Security OAuth 2实战

1. Spring Authorization Server 是什么 Spring Authorization Server 是一个框架,它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产品提供了一个安全、轻…...

二次供水物联网:HiWoo Cloud助力城市水务管理升级

随着城市化的快速推进,二次供水系统作为城市基础设施的重要组成部分,其稳定运行和高效管理显得至关重要。然而,传统的二次供水管理方式在应对复杂多变的城市供水需求时,显得力不从心。为了破解这一难题,HiWoo Cloud平台…...

P1015 [NOIP1999 普及组] 回文数

题目传送门 题目描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。 例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个…...

【MATLAB】兔子机器人动力学模型解读(simulink中的simscape的各模块介绍)

1、动力学模型 Rectangular Joint 控制平面上(x,y轴)的移动,去掉以后,机器人在原地翻滚不移动 Rigid Transform 坐标转换,B站视频已收藏 去掉,机体与地面贴合 此处的作用是设定机体的初…...

小程序配置服务器域名

要配置小程序的服务器域名,您需要在小程序后台进行以下步骤: 登录小程序后台,进入开发设置页面。找到服务器域名配置选项,点击添加域名。输入您的服务器域名,可以添加多个域名,包括请求域名、上传文件域名…...

探究全链路压力测试的含义与重要性

全链路压力测试是指对整个应用系统的各个环节或组件进行压力测试,以模拟实际生产环境中的用户负载和流量,评估系统在高负载条件下的性能表现。 1. 全链路压力测试的含义 全链路压力测试涉及系统的所有组件和环节,包括前端用户界面、应用服务器…...

代码随想录算法训练营day64 || 84. 柱状图中最大的矩形

单调栈,又一次经典来袭! LeetCode:84.柱状图中最大的矩形_哔哩哔哩_bilibili 首先补充昨天接雨水题目解法的更新,代码随想录 中给出双指针和单调栈的解法,其中所采用的思想是计算每一列可以容纳的雨水,非常…...

图的简单介绍

定义及术语 G(V,E):图G的顶点集为V,边集为E。分为有向图和无向图两类。 顶点的度:与该结点相连的边的条数。 出度:顶点的出边条数 入度:顶点的入边条数 顶点的权值称为点权,边的权值称为边权。 存储 1.邻…...

【C#小知识】c#中的delegate(委托)和event(事件)

今天来介绍一下delegate和event。delegate在c#中可以定义一个函数类型,可以将函数作为一个对象来使用。event在c#中则可以看做一个函数的集合,event中包含了一个或多个函数。 delegate using System;public class MyClass {//定义委托public delegate v…...

车规级存储芯片SPI NOR Flash

国产SPI NOR Flash厂家聚辰提供多种容量选择,可满足多种实时操作系统所需的不同存储空间;并且,拥有四种不同电压范围,分别为3V、1.8V、1.2V以及针对电池供电应用推出的1.65V~3.6V宽压供电的产品系列;同时,提…...

CSS轻松学:简单易懂的CSS基础指南

css基础 更多web开发知识欢迎访问我的专栏>>> 01-CSS初体验 层叠样式表 (Cascading Style Sheets,缩写为 CSS),是一种 样式表 语言,用来描述 HTML 文档的呈现(美化内容)。 书写位置:…...

06 Qt自绘组件:Switch动画开关组件

系列文章目录 01 Qt自定义风格控件的基本原则-CSDN博客 02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客 03 从QLabel聊起:自定义控件扩展-文本控件-CSDN博客 04 自定义Button组件:令人抓狂的QToolButton文本图标居中问题-CSDN博客 0…...

大语言模型LLM分布式训练:大规模数据集上的并行技术全景探索(LLM系列03)

文章目录 大语言模型LLM分布式训练:大规模数据集上的并行技术全景探索(LLM系列03)1. 引言1.1 大语言模型(LLM)的重要性及其规模化挑战1.2 分布式训练策略的需求 2. 分布式训练基础原理2.1 并行计算的基本概念与分类 3.…...

98.验证二叉搜索树

98.验证二叉搜索树 思路 1.一开始使用递归,想当前节点满足条件后,再使左右子树分别满足条件。失败,只考虑了节点与左右子树的大小,未考虑隔代节点的关系。 2.转变思路,使用中序遍历的方法,从第一个节点开…...

2月21日,每日信息差

🎖 素材来源官方媒体/网络新闻 🎄 10 家央企签订倡议书:将主动向社会开放人工智能应用场景 🌍 上海成为首个固定资产投资破万亿的一线城市 🌋 特斯拉扩建德国工厂的计划遭当地居民反对 🎁 加拿大公司利用木…...

android.text.BoringLayout.isBoring 的 NullPointerException

都是重写TextView.settext()函数导致的坑~ override fun setText(text: CharSequence?, type: BufferType?) {if (text.isNullOrEmpty()) {return}//业务代码super.setText(text, type)} java.lang.NullPointerException at android.text.BoringLayout.isBoring(BoringLayo…...

C++ 高频考点

1. C/C内存有哪几种类型? C中,内存分为5个区:堆(malloc)、栈(如局部变量、函数参数)、程序代码区(存放二进制代码)、全局/静态存储区(全局变量、static变量)和常量存储区(常量&…...

Ubuntu安装SVN服务并结合内网穿透实现公网访问本地存储文件

最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svns…...

2月20日,每日信息差

第一、中国联通 1 月智慧客服客户问题解决率为 97.9%,大联接用户达 10.02 亿户,5G 套餐用户约 2.64 亿户,物联网终端连接约 5.06 亿户。5G 行业虚拟专网服务客户数为 9185 个,智慧客服问题解决率 97.9%,智能服务占比 8…...

Visual Studio清单作用

1、作用: 制定程序依赖的C运行库的dll及版本,包括mfc,atl,crt等,在Visual Studio安装目录下的vc/redist下有debug和release版本 2、确定应用程序依赖哪些visual C 库方法: 查看项目-》项目设置-》常规&…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子&#xff08…...

React Native 导航系统实战(React Navigation)

导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色&#xf…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...