You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django视图间传值方法及Fitbit OAuth2授权后令牌获取问询

Fitbit OAuth2.0 后续流程 + Django 视图间传数据指南

我之前刚好做过Django对接Fitbit的项目,这两个问题我太熟了,给你梳理清楚:

一、Fitbit OAuth2.0 授权码换令牌及后续流程

你已经拿到授权码了,接下来就是用这个code去换访问令牌,完整流程是这样的:

1. 先在Django配置里存好Fitbit参数

先把你的Fitbit密钥信息放到settings.py里,方便后续调用:

# settings.py
FITBIT_CLIENT_ID = '你的Fitbit Client ID'
FITBIT_CLIENT_SECRET = '你的Fitbit Client Secret'
FITBIT_REDIRECT_URI = 'https://localhost:8000/你的回调路径'  # 和授权链接里的完全一致

2. 构造令牌请求并获取令牌

Fitbit的令牌端点是https://api.fitbit.com/oauth2/token,需要发送POST请求,核心要求如下:

  • 必须参数:grant_type=authorization_code、你的授权码code、重定向URLredirect_uri、client_id
  • 认证方式:用Basic Auth,把{client_id}:{client_secret}做Base64编码后放在请求头,或者直接用requests库的auth参数自动处理

Django视图实现示例

import requests
from django.shortcuts import redirect, render
from django.conf import settings
from django.contrib import messages

def fitbit_callback(request):
    # 提取授权码
    code = request.GET.get('code')
    if not code:
        messages.error(request, '未获取到Fitbit授权码')
        return redirect('home')
    
    # 构造令牌请求
    token_url = "https://api.fitbit.com/oauth2/token"
    payload = {
        'grant_type': 'authorization_code',
        'code': code,
        'redirect_uri': settings.FITBIT_REDIRECT_URI,
        'client_id': settings.FITBIT_CLIENT_ID,
    }
    # 自动处理Basic Auth认证
    auth = (settings.FITBIT_CLIENT_ID, settings.FITBIT_CLIENT_SECRET)
    
    response = requests.post(token_url, data=payload, auth=auth)
    if response.status_code != 200:
        error_msg = response.json().get('errors', [{}])[0].get('message', '未知错误')
        messages.error(request, f'获取令牌失败:{error_msg}')
        return redirect('home')
    
    # 解析令牌数据
    token_data = response.json()
    access_token = token_data['access_token']
    refresh_token = token_data['refresh_token']
    expires_in = token_data['expires_in']  # 令牌有效期(秒,Fitbit默认8小时)
    
    # 存储令牌(关键!)
    # 方式1:存在用户Session(适合临时测试,会话结束失效)
    request.session['fitbit_access_token'] = access_token
    request.session['fitbit_refresh_token'] = refresh_token
    # 方式2:存在用户关联模型(生产环境推荐,需先给User模型加OneToOne关联的FitbitProfile)
    # request.user.fitbit_profile.access_token = access_token
    # request.user.fitbit_profile.refresh_token = refresh_token
    # request.user.fitbit_profile.save()
    
    # 现在可以用access_token调用Fitbit API了,比如获取用户今日步数
    api_url = "https://api.fitbit.com/1/user/-/activities/steps/date/today/1d.json"
    headers = {'Authorization': f'Bearer {access_token}'}
    api_response = requests.get(api_url, headers=headers)
    if api_response.status_code == 200:
        steps = api_response.json()['activities-steps'][0]['value']
        messages.success(request, f'授权成功!今日步数:{steps}')
        return redirect('fitbit_dashboard')
    
    messages.warning(request, '授权成功但暂时无法获取数据')
    return redirect('fitbit_dashboard')

3. 令牌过期后的刷新流程

当access_token过期后,用refresh_token换全新令牌:

def refresh_fitbit_token(request):
    refresh_token = request.session.get('fitbit_refresh_token')
    if not refresh_token:
        return redirect('fitbit_auth')
    
    token_url = "https://api.fitbit.com/oauth2/token"
    payload = {
        'grant_type': 'refresh_token',
        'refresh_token': refresh_token,
        'client_id': settings.FITBIT_CLIENT_ID,
    }
    auth = (settings.FITBIT_CLIENT_ID, settings.FITBIT_CLIENT_SECRET)
    
    response = requests.post(token_url, data=payload, auth=auth)
    if response.status_code == 200:
        new_token_data = response.json()
        # 更新存储的令牌
        request.session['fitbit_access_token'] = new_token_data['access_token']
        # 注意:Fitbit可能返回新的refresh_token,记得一起更新
        if 'refresh_token' in new_token_data:
            request.session['fitbit_refresh_token'] = new_token_data['refresh_token']
        return True
    return False

二、Django视图间传递数据的正确方式

根据不同场景选对应的方法:

1. Session存储(推荐敏感/大量数据)

适合传递用户专属的敏感数据(比如上面的Fitbit令牌),会话有效期内都能访问:

# 源视图存数据
def source_view(request):
    request.session['user_preference'] = {'theme': 'dark', 'notifications': True}
    return redirect('target_view')

# 目标视图取数据
def target_view(request):
    pref = request.session.get('user_preference')
    if pref:
        # 使用后建议删除,避免冗余
        del request.session['user_preference']
        return render(request, 'target.html', {'pref': pref})
    return render(request, 'target.html')

2. Messages框架(推荐提示信息)

专门用来传递操作提示(成功/失败/提醒),模板里可以直接渲染:

from django.contrib import messages

def source_view(request):
    messages.success(request, '数据提交成功!')
    messages.warning(request, '请尽快完善个人信息')
    return redirect('target_view')

# 模板(比如base.html)里添加渲染代码
{% if messages %}
<div class="messages">
    {% for message in messages %}
    <div class="alert alert-{{ message.tags }}">{{ message }}</div>
    {% endfor %}
</div>
{% endif %}

3. URL参数(适合少量非敏感数据)

传递简单的ID、状态码等非敏感数据,直接拼在重定向URL里:

# 源视图
def source_view(request):
    order_id = 1001
    # 用reverse生成URL更规范
    from django.urls import reverse
    return redirect(reverse('order_detail', kwargs={'order_id': order_id}))

# urls.py配置
path('orders/<int:order_id>/', order_detail_view, name='order_detail')

# 目标视图
def order_detail_view(request, order_id):
    # 使用order_id查询订单
    return render(request, 'order_detail.html', {'order_id': order_id})

4. 表单POST传递(适合提交后跳转)

如果是表单提交后跳转到处理视图,直接在POST请求里传递数据,但一般建议先处理数据,再用Session/Messages传递结果,避免重复提交。


内容的提问来源于stack exchange,提问作者Henry La

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:55:47