DRF之JWT认证
一、JWT认证
在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制。
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。



1.1 构成和工作原理
JWT的构成
JWT就是一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).
1.1.1 header
jwt的头部承载两部分信息:
- 声明类型,这里是jwt
- 声明加密的算法 通常直接使用 HMAC SHA256
完整的头部就像下面这样的JSON:
{'typ': 'JWT','alg': 'HS256'
}
然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
1.1.2 payload
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
- 标准中注册的声明
- 公共的声明
- 私有的声明
标准中注册的声明 (建议但不强制使用) :
- iss: jwt签发者
- sub: jwt所面向的用户
- aud: 接收jwt的一方
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- nbf: 定义在什么时间之前,该jwt都是不可用的.
- iat: jwt的签发时间
- jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避时序攻击。
公共的声明 : 公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
私有的声明 : 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
定义一个payload:
{"sub": "1234567890","name": "John Doe","admin": true
}
然后将其进行base64加密,得到JWT的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
1.1.3 signature
JWT的第三部分是一个签证信息,这个签证信息由三部分组成:
- header (base64后的)
- payload (base64后的)
- secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
将这三部分用.连接成一个完整的字符串,构成了最终的jwt:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
关于签发和核验JWT,我们可以使用Django REST framework JWT扩展来完成。
1.2 本质原理
jwt认证算法:签发与校验
"""
1)jwt分三段式:头.体.签名 (head.payload.sgin)
2)头和体是可逆加密,让服务器可以反解出user对象;签名是不可逆加密,保证整个token的安全性的
3)头体签名三部分,都是采用json格式的字符串,进行加密,可逆加密一般采用base64算法,不可逆加密一般采用hash(md5)算法
4)头中的内容是基本信息:公司信息、项目组信息、token采用的加密方式信息
{"company": "公司信息",...
}
5)体中的内容是关键信息:用户主键、用户名、签发时客户端信息(设备号、地址)、过期时间
{"user_id": 1,...
}
6)签名中的内容时安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全码 进行md5加密
{"head": "头的加密字符串","payload": "体的加密字符串","secret_key": "安全码"
}
"""
签发:根据登录请求提交来的 账号 + 密码 + 设备信息 签发 token
"""
1)用基本信息存储json字典,采用base64算法加密得到 头字符串
2)用关键信息存储json字典,采用base64算法加密得到 体字符串
3)用头、体加密字符串再加安全码信息存储json字典,采用hash md5算法加密得到 签名字符串账号密码就能根据User表得到user对象,形成的三段字符串用 . 拼接成token返回给前台
"""
校验:根据客户端带token的请求 反解出 user 对象
"""
1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理
2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间和设备信息都是安全信息,确保token没过期,且时同一设备来的
3)再用 第一段 + 第二段 + 服务器安全码 不可逆md5加密,与第三段 签名字符串 进行碰撞校验,通过后才能代表第二段校验得到的user对象就是合法的登录用户
"""
drf项目的jwt认证开发流程(重点)
"""
1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中2)校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户注:登录接口需要做 认证 + 权限 两个局部禁用
"""
1.2.1 补充base64编码解码
import base64
import json
dic_info={"sub": "1234567890","name": "lqz","admin": True
}
byte_info=json.dumps(dic_info).encode('utf-8')
# base64编码
base64_str=base64.b64encode(byte_info)
print(base64_str)
# base64解码
base64_str='eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9'
str_url = base64.b64decode(base64_str).decode("utf-8")
print(str_url)
二 drf-jwt安装和简单使用
2.1官网
http://getblimp.github.io/django-rest-framework-jwt/
2.2 安装
pip install djangorestframework-jwt
2.3 使用:
# 1 创建超级用户
python3 manage.py createsuperuser
# 2 配置路由urls.py
from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [path('login/', obtain_jwt_token),
]
# 3 postman测试
向后端接口发送post请求,携带用户名密码,即可看到生成的token# 4 setting.py中配置认证使用jwt提供的jsonwebtoken
# 5 postman发送访问请求(必须带jwt空格)
三 实战之使用Django auth的User表自动签发
3.1 配置setting.py
import datetime
JWT_AUTH = {# 过期时间1天'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),# 自定义认证结果:见下方序列化user和自定义response# 如果不自定义,返回的格式是固定的,只有token字段'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
}
3.2 编写序列化类ser.py
from rest_framework import serializers
from users import models
class UserModelSerializers(serializers.ModelSerializer):class Meta:model = models.UserInfofields = ['username']
3.3 自定义认证返回结果(setting中配置的)
#utils.py
from users.ser import UserModelSerializers
def jwt_response_payload_handler(token, user=None, request=None):return {'status': 0,'msg': 'ok','data': {'token': token,'user': UserModelSerializers(user).data}}
3.4 基于drf-jwt的全局认证:
#app_auth.py(自己创建)
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.authentication import get_authorization_header,jwt_get_username_from_payload
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthenticationclass JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):def authenticate(self, request):jwt_value = get_authorization_header(request)if not jwt_value:raise AuthenticationFailed('Authorization 字段是必须的')try:payload = jwt_decode_handler(jwt_value)except jwt.ExpiredSignature:raise AuthenticationFailed('签名过期')except jwt.InvalidTokenError:raise AuthenticationFailed('非法用户')user = self.authenticate_credentials(payload)return user, jwt_value
3.5 全局使用
# setting.py
REST_FRAMEWORK = {# 认证模块'DEFAULT_AUTHENTICATION_CLASSES': ('users.app_auth.JSONWebTokenAuthentication',),
}
3.6 局部启用禁用
# 局部禁用
authentication_classes = []
# 局部启用
from user.authentications import JSONWebTokenAuthentication
authentication_classes = [JSONWebTokenAuthentication]
# 实际代码如下view.py
# 自定义Response
class CommonResponse(Response):def __init__(self,status,msg,data='',*args,**kwargs):dic={'status':status,'msg':msg,'data':data}super().__init__(data=dic,*args,**kwargs)
# 测试订单接口
from users.app_auth import JSONWebTokenAuthentication
class OrderView(APIView):# authentication_classes = [JSONWebTokenAuthentication]authentication_classes = []def get(self,request):return CommonResponse('100', '成功',{'数据':'测试'})
四 实战之自定义User表,手动签发
4.1 手动签发JWT:
# 可以拥有原生登录基于Model类user对象签发JWT
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLERpayload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
4.2 编写登陆视图类
# views.py
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from users.models import User
class LoginView(APIView):authentication_classes = []def post(self,request):username=request.data.get('username')password=request.data.get('password')user=User.objects.filter(username=username,password=password).first()if user: # 能查到,登陆成功,手动签发payload = jwt_payload_handler(user)token = jwt_encode_handler(payload)return CommonResponse('100','登陆成功',data={'token':token})else:return CommonResponse('101', '登陆失败')
4.3 编写认证组件
# app_auth.py
from users.models import User
class MyJSONWebTokenAuthentication(BaseAuthentication):def authenticate(self, request):jwt_value = get_authorization_header(request)if not jwt_value:raise AuthenticationFailed('Authorization 字段是必须的')try:payload = jwt_decode_handler(jwt_value)except jwt.ExpiredSignature:raise AuthenticationFailed('签名过期')except jwt.InvalidTokenError:raise AuthenticationFailed('非法用户')username = jwt_get_username_from_payload(payload)print(username)user = User.objects.filter(username=username).first()print(user)return user, jwt_value
4.4 登陆获取token

4.5编写测试接口
from users.app_auth import JSONWebTokenAuthentication,MyJSONWebTokenAuthentication
class OrderView(APIView):# authentication_classes = [JSONWebTokenAuthentication]authentication_classes = [MyJSONWebTokenAuthentication]def get(self,request):print(request.user)return CommonResponse('100', '成功',{'数据':'测试'})
4.6 测试

五、源码分析
5.1drf—jwt的签发源码分析
5.1.1 from rest_framework_jwt.views import obtain_jwt_token
obtain_jwt_token就是ObtainJSONWebToken.as_view()---》视图类.as_view()
视图类
class ObtainJSONWebToken(JSONWebTokenAPIView):serializer_class = JSONWebTokenSerializer
父类:JSONWebTokenAPIView
class JSONWebTokenAPIView(APIView):# 局部禁用掉权限和认证permission_classes = ()authentication_classes = ()def post(self, request, *args, **kwargs):
serializer=JSONWebTokenSerializer(data=request.data)
serializer = self.get_serializer(data=request.data)
调用序列化列的is_valid---》字段自己的校验规则,局部钩子和全局钩子
读JSONWebTokenSerializer的局部或全局钩子
if serializer.is_valid(): # 全局钩子在校验用户,生成token
从序列化类中取出user
user = serializer.object.get('user') or request.user
从序列化类中取出token
token = serializer.object.get('token')
定制返回格式的时候,写的就是这个函数
response_data = jwt_response_payload_handler(token, user, request)response = Response(response_data)return responsereturn Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
JSONWebTokenSerializer的全局钩子
class JSONWebTokenSerializer(Serializer):def validate(self, attrs):# attrs前端传入的,校验过后的数据 {username:lqz,password:lqz12345}
credentials = {'username': attrs.get('usernme'),'password': attrs.get('password')}if all(credentials.values()): # 校验credentials中字典的value值是否都不为空# user=authenticate(username=前端传入的,password=前端传入的)# auth模块的用户名密码认证函数,可以传入用户名密码,去auth的user表中校验用户是否存在# 等同于:User.object.filter(username=username,password=加密后的密码).first()
user = authenticate(**credentials)if user:if not user.is_active:msg = _('User account is disabled.')raise serializers.ValidationError(msg)payload = jwt_payload_handler(user)return {'token': jwt_encode_handler(payload),'user': user}else:msg = _('Unable to log in with provided credentials.')raise serializers.ValidationError(msg)else:msg = _('Must include "{username_field}" and "password".')msg = msg.format(username_field=self.username_field)raise serializers.ValidationError(msg)
5.2认证源码
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
JSONWebTokenAuthentication
class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):def get_jwt_value(self, request):# auth=['jwt','token串']auth = get_authorization_header(request).split()auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower()if not auth:if api_settings.JWT_AUTH_COOKIE:return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE)return Noneif smart_text(auth[0].lower()) != auth_header_prefix:return Noneif len(auth) == 1:msg = _('Invalid Authorization header. No credentials provided.')raise exceptions.AuthenticationFailed(msg)elif len(auth) > 2:msg = _('Invalid Authorization header. Credentials string ''should not contain spaces.')raise exceptions.AuthenticationFailed(msg)return auth[1] # token串
父类中找:BaseJSONWebTokenAuthentication---》authenticate,找到了
class BaseJSONWebTokenAuthentication(BaseAuthentication):def authenticate(self, request):# 拿到前端传入的token,前端传入的样子是 jwt token串jwt_value = self.get_jwt_value(request)# 如果前端没传,返回None,request.user中就没有当前登录用户# 如果前端没有携带token,也能进入到视图类的方法中执行,控制不住登录用户# 所以咱们才加了个权限类,来做控制if jwt_value is None:return Nonetry:payload = jwt_decode_handler(jwt_value)except jwt.ExpiredSignature:msg = _('Signature has expired.')raise exceptions.AuthenticationFailed(msg)except jwt.DecodeError:msg = _('Error decoding signature.')raise exceptions.AuthenticationFailed(msg)except jwt.InvalidTokenError:raise exceptions.AuthenticationFailed()
通过payload拿到当前登录用户
user = self.authenticate_credentials(payload)return (user, jwt_value)
如果用户不携带token,也能认证通过
所以我们必须加个权限类来限制
class IsAuthenticated(BasePermission):def has_permission(self, request, view):return bool(request.user and request.user.is_authenticated)
相关文章:
DRF之JWT认证
一、JWT认证 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制。 Json web token (JWT), 是为了在网络应用环…...
华为OD机试真题 Java 实现【放苹果】【2022Q4 100分】
一、题目描述 把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法? 注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法。 数据范围:0≤m≤10 ,1≤n≤10 。 二、输入描述 输入两个int整数。 三、输出描述 输…...
拼多多继续ALL IN
2023年注定是中国电商不平凡的一年。 随着网购用户数量见顶,经济形势进入新常态,电商平台已经来到了短兵相接的肉搏战阶段。 此刻的618大促,硝烟弥漫,刀光剑影,电商“决战”似乎是迫在眉睫。对各个平台来说,…...
Unity的IPostprocessBuildWithReport:深入解析与实用案例
Unity IPostprocessBuildWithReport Unity IPostprocessBuildWithReport是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目后自动执行一些操作,并且可以获取构建报告。这个功能可以帮助开发提高工作效率,减少手动操作的时间和错误…...
九、Spring Cloud—gateway网关
一、引言 每个微服务都需和前端进行通信,解决每个微服务请求时的鉴权、限流、权限校验、跨域等逻辑,放在一个统一的地方进行使用。 在微服务架构中,网关是一个重要的组件,它作为系统的入口,负责接收所有的客户端请求…...
ARM微架构与程序编写
目录 1.流水线 2.指令流水线 3. 多核处理器编辑 4. 工程搭建 4.1为Keil软件配置编译工具链 5.程序编写 5.1 数据处理指令 5.2 带标志位的加法ADC ADDS 5.3 跳转指令B\BL 5.4 单寄存器内存访问 5.5 批量寄存器内存访问 5.6 栈的应用->叶子函数的调用过程 5.…...
Windows下利用Anaconda创建多个CUDA环境
参考 https://blog.csdn.net/qq_42395917/article/details/126237388 https://blog.csdn.net/qq_42406643/article/details/109545766 (待学习补充) https://blog.csdn.net/qq_43919533/article/details/125694437 (待学习补充) 安装cudatoolkit和cudnn # 前提是我已经安装了…...
C SS复习笔记
1.img标签 img的src属性是图片显示不出来时显示的文字 ing的title属性是光标放到图片上,提示的文字 2.a标签 a标签的target属性表示打开窗口的方式,默认的值是_self表示当前窗口的打开页面,_blank表示新窗口打开页面。 a标签的href链接分…...
LeetCode 225 用队列实现栈
题目: 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回…...
Java对象的共享
要编写正确的并发程序,关键问题在于:在访问共享的可变状态时需要进行正确的管理。第2章介绍了如何通过同步来避免多个线程在同一时刻访问相同的数据,而本章将介绍如何共享和发布对象,从而使它们能够安全地由多个线程同时访问。这两…...
漏洞概述-0day漏洞利用原理(0)
0day专题对作者来说是一个很大的挑战,但无论有多难,作者会坚持进行大量的对新旧技术(精通二进制、汇编语言、操作系统底层的知识)实践并尽可能做到完善,最终利用技术发扬正能量。 bug 与漏洞 随着现代软件工业的发展,软件规模不断扩大,软件内部的逻辑也变得异常复杂。为…...
交换机的4种网络结构方式:级联方式、堆叠方式、端口聚合方式、分层方式
交换机是计算机网络中重要的网络设备之一,用于实现局域网(LAN)内部的数据转发和通信。交换机可以采用不同的网络结构方式来满足不同的网络需求和拓扑结构。本文将详细介绍交换机的四种网络结构方式:级联方式、堆叠方式、端口聚合方…...
firewall-cmd防火墙策略
--permanent 永久生效,重启后规则不消失 不执行 firewall-cmd --reload 命令配置不生效 添加单个IP为白名单 firewall-cmd --permanent --zonepublic -add-rich-rulerule family"ipv4" source address"IP" accept 删除白名单 firewall-cmd --…...
解决SQLException: Incorrect string value异常
java开发中会遇到如下异常: org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: java.sql.SQLException: Incorrect string value: \xF0\x9F\x95\xB32:... for column baseInfo at row 1 ### The error may involve com.f…...
桂院校园导航 导入 与 配置教程
将 静态项目/云开发项目 文件夹下最新版本的 文件夹下的 项目 的整个文件夹 复制到项目路径下(比如 D:\WeChatProjects),强烈建议不要直接扔在桌面上 云开发项目 需开通 云开发 功能(首月免费,次月19.9)&am…...
Linux上安装jdk Tomcat mysql redis
1.安装JDk 1.1这里使用xshell中xfxp进行文件的上传,将jdk二进制包上传到Linux服务器上 下载地址:Java Downloads | Oracle 或者这里有下载好的安装包:链接:https://pan.baidu.com/s/1ZSJxBDzDaTwCH2IG-d2Gig 提取码:…...
Postman中加url环境变量和token全局变量
环境变量引用 语法:{{变量名}} 环境变量分类 1. 全局变量:全局有效,在Postman中的任何集合中都可以使用该变量,作用域最大。 2. 环境变量:要申明环境变量,先要创建环境,然后在该环境中创建变…...
多线程事务回滚方法
多线程事务回滚方法 介绍案例演示线程池配置异常类实体类控制层业务层mapper工具类验证 解决方案使用sqlSession控制手动提交事务SqlSessionTemplate注入容器中改造业务层验证成功操作示例业务层改造 介绍 1.最近有一个大数据量插入的操作入库的业务场景,需要先做一…...
java单元测试( Hamcrest 断言)
java单元测试( Hamcrest 断言) 单元测试特征: 1 范围狭窄 2 限于单一类或方法 3 体积小 为什么要编写单元测试? 为了防止错误(很明显!) 而且还可以提高开发人员的生产力,因为单元测试: (1) 帮助实施——在…...
讨论和总结 树模型 的三种序列化 方式的区别(模型存储大小、序列化所用内存、序列化速度)...
一、前言 本文总结常用树模型: rf,xgboost,catboost和lightgbm等模型的保存和加载(序列化和反序列化)的多种方式,并对多种方式从运行内存的使用和存储大小做对比 二、模型 2.1 安装环境 pip install xgboos…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
