工具-百度云盘服务-身份认证

目标

复制代码
通过百度网盘API的方式去获取网盘中的文件,要实现这的第一步就是需要获取网盘的权限。

资料(参考)

复制代码
如果期望应用访问用户的网盘文件,则需要经过用户同意,这个流程被称为"授权"。百度网盘开放平台基于 OAuth2.0 接入授权。OAuth2.0 是一种授权协议,通过该协议用户可以授权开发者应用访问个人网盘信息与文件。
用户同意授权后,开发者应用会获取到一个 Access Token,该 Access Token 是用户同意授权的凭证。开发者应用需要依赖 Access Token 凭证调用百度网盘公开API,实现访问用户网盘信息与授权资源。
关于实现用户授权,您可以选择授权码模式、简化模式或者设备码模式实现。
当前百度网盘开放平台支持三种授权模式:授权码模式(Authorization Code)、简化模式(Implicit Grant)、设备码模式(Device Code)。您可以根据自身业务,选择合适的授权模式,实现用户授权。
授权模式 描述 使用场景 有效期
授权码模式(Authorization Code) 用户授权后生成授权码 Code,开发者应用通过 Code 换取 Access Token。 适用于 有 Server 端 的应用。 Access Token 有效期30天,过期后支持刷新。
简化模式(Implicit Grant) 无需通过 Code 换取 Access Token,直接获取 Access Token。 适用于 无 Server 端配合 的应用。 Access Token 有效期30天,过期后不支持刷新, 用户需重新登录授权。
设备码模式(Device Code) 获取设备码,用户授权后,开发者应用通过设备码换取 Access Token。 适用于 弱输入设备 的应用(不支持浏览器或输入受限的设备,如儿童手表)。 Device Code只能使用一次,Access Token过期后支持刷新。
授权注意事项:
  • Access Token 有效期30天,过期后支持刷新,刷新后的 Access Token 有效期仍为 30 天。
  • 刷新Access Token请按需刷新,不需要不停的刷新。
  • 刷新请求,如果API返回失败,旧的refresh_token会失效,此时需要重新发起授权请求,获取新的 Access Token、refresh_token,而不是使用旧的 refresh_token 循环再发起刷新请求。
  • refresh_token 只支持使用一次,refresh_token 使用后失效,下次刷新 Access Token 时需要使用上一次刷新请求响应中的 refresh_token。

准备

在授权之前,您需要先完成创建自己的应用。

主要包括以下流程:

  1. 进入百度网盘开放平台,点击右上角 "申请接入"。
  2. 登录您的百度帐号。
  3. 完成开发者认证,我们提供了两种认证类型供您选择:个人认证、企业认证。
  4. 前往控制台创建自己的应用,生成AppID、AppKey、SecretKey、SignKey等信息。
    目前个人认证下可最多创建 2 个应用,企业认证下可最多创建 10 个应用。
    可创建两种类型的应用:硬件应用和软件应用。
  5. 至此,完成应用的创建。

实现逻辑

授权码模式适用于有 Server 端的应用。我们这次实现是选用的授权码模式。

开发者应用在获取用户的授权码 Code 之后,通过 Code 换取 Access Token 凭证

Access Token 有效期30天,过期后支持刷新,刷新后的 Access Token 有效期仍为 30 天 ,刷新Access Token请按需刷新,不需要不停的刷新。

刷新请求,如果API返回失败,旧的refresh_token会失效,此时需要重新发起授权请求,获取新的 Access Token、refresh_token,而不是使用旧的 refresh_token 循环再发起刷新请求。
refresh_token 只支持使用一次 ,refresh_token 使用后失效,下次刷新 Access Token 时需要使用上一次刷新请求响应中的refresh_token。
获取到的授权码 code 有效期 10 分钟,且仅一次有效。

简单介绍时序图的流程,如下:

  1. 用户选择通过百度账号登录开发者应用。
  2. 开发者应用发起授权码 Code 请求。
  3. 百度 OAuth 服务器展示授权页面给用户,用户登录并同意授权。
  4. 用户同意授权后,百度 OAuth 服务器会将页面跳转至开发者应用配置的回调地址,返回授权码 Code。
  5. 开发者应用发起 Code 换取 Access Token 请求。
  6. 百度 OAuth 服务器返回 Access Token 凭证。

实现步骤:

  1. 获取授权码,需要页面登录认证,且需要传入参数(授权码只可用一次 )
    登录链接格式: https://openapi.baidu.com/oauth/2.0/authorize?client_id=app_key\&device_id=app_id\&errmsg=Auth+Login+Ptoken+Error\&errno=10\&redirect_uri=oob\&response_type=code\&scope=basic%2Cnetdisk\&ssnerror=1
    需要传入参数(后面几个参数可以固定)为: device_id client_id redirect_uri=oob response_type=code scope=basic,netdisk
python 复制代码
	# 1. 获取授权码 需页面登录认证
    def get_authorization_code(self):
        import requests
        url = 'http://openapi.baidu.com/oauth/2.0/authorize'
        payload = {
            'response_type':'code',
            'device_id': self.device_id,
            'client_id': self.client_id,
            'scope': 'basic, netdisk',
            'redirect_uri': 'oob'
        }
        headers = {
            'User-Agent': 'pan.baidu.com'
        }
        print(url)
        response = requests.request("GET", url, headers=headers, data=payload)
        print(response.text)
  1. 使用授权码换取AccessToken凭证
    上面资料中提到token的有效期是30天,该请求会返回一个refresh_token值,由于后续刷新需要上一次的值,所以后续我们需要考虑把这个值保存到本地。
python 复制代码
	# 2. 换取AccessToken凭证 将token信息保存到本地,支持后续读取更新
    def oauthtoken_authorizationcode(self, file_path = 'tokens.json'):
        with openapi_client.ApiClient() as api_client:
            api_instance = auth_api.AuthApi(api_client)
            code = self.code
            client_id = self.client_id
            client_secret = self.client_secret
            redirect_uri = self.redirect_uri
            try:
                api_response = api_instance.oauth_token_code2token(code, client_id, client_secret, redirect_uri)
                access_token = self.save_tokens_info(api_response, file_path)
                return access_token, file_path
            except openapi_client.ApiException as e:
                print("使用code换取AccessToken凭证失败: %s\n" % e)
  1. 刷新AccessToken
    由于获取授权码需要页面验证,开发使用时很不方便,所以需要把token信息保存到本地,用了支撑刷新及更新token
    实现
python 复制代码
	# 3. 刷新 Access Token 将token信息保存到本地
    def oauthtoken_refreshtoken(self, file_path = 'tokens.json'):
        with open(file_path, 'r') as f:
            data = json.load(f)
        print(data)
        if (datetime.datetime.strptime(data['expires_time'], "%Y-%m-%d %H:%M:%S") > datetime.datetime.now()):
            print('access_token:',data['access_token'],',未过期,过期时间:',data['expires_time'])
            return data['access_token']
        else:
            with openapi_client.ApiClient() as api_client:
                api_instance = auth_api.AuthApi(api_client)
                refresh_token = data['refresh_token']
                client_id = self.client_id
                client_secret = self.client_secret
                try:
                    api_response = api_instance.oauth_token_refresh_token(refresh_token, client_id, client_secret)
                    access_token = self.save_tokens_info(api_response, file_path)
                    return access_token
                except openapi_client.ApiException as e:
                    print("刷新Access Token失败: %s\n" % e)

工具函数: 保存到本地

python 复制代码
# 将token信息保存下来
    def save_tokens_info(self, api_response, file_path):
        tokens_dict = {'access_token': api_response.access_token,
                       'expires_in': api_response.expires_in,
                       'expires_time': (datetime.datetime.now() + datetime.timedelta(
                           seconds=api_response.expires_in)).strftime("%Y-%m-%d %H:%M:%S"),
                       'refresh_token': api_response.refresh_token,
                       'scope': api_response.scope,
                       'session_key': api_response.session_key,
                       'session_secret': api_response.session_secret}
        print('tokens信息为:', tokens_dict)
        # 将数据写入json文件
        with open(file_path, 'w') as f:
            json.dump(tokens_dict, f)
        print('tokens结果保存到本地:', file_path)
        return api_response.access_token

最终运行

python 复制代码
if __name__ == '__main__':
    client = Baidu()
	client.oauthtoken_authorizationcode()
    client.oauthtoken_refreshtoken()

总结

在调试过程时,一次性code和一次性refresh使用时很不便利,这两个变量不是时效性的,是需要注意的。

相关推荐
_深海凉_10 分钟前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦32 分钟前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu41 分钟前
Python 语法之数据结构详细解析
python
AI问答工程师1 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
zfan5202 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕2 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙2 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
格鸰爱童话3 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
悟空爬虫-彪哥3 小时前
VRChat开发环境配置,零基础教程
python
数据知道3 小时前
《 Claude Code源码分析与实践》专栏目录
python·ai·github·claude code·claw code