首页 > 编程问答 >django OAuth 工具包未获取重定向 URI

django OAuth 工具包未获取重定向 URI

时间:2024-07-26 12:53:41浏览次数:10  
标签:python django session django-oauth django-oauth-toolkit

我正在使用 Django OAuth 工具包并使用以下代码进行 OAuth 实现

Application = get_application_model()

def oauth_login(request):
    app = Application.objects.get(name="App")
    #redirect_uri = request.GET.get("redirect_uri", "http://test.com:8000/callback")
    #redirect_uri = request.GET.get("redirect_uri", "http://test.com:8002/malicious_redirect.html")
    redirect_uri = request.POST.get("redirect_uri", "http://test.com:8002/malicious_redirect.html")
    
    authorization_url = (
        f"http://test.com:8000/o/authorize/?client_id={app.client_id}&response_type=code&redirect_uri={redirect_uri}"
    )
    return redirect(authorization_url)

def oauth_callback(request):
    code = request.GET.get("code")
    
    if not code:
        return JsonResponse({'error': 'missing_code', 'details': 'Missing code parameter.'}, status=400) 

    token_url = "http://test.com:8000/o/token/"
    client_id = Application.objects.get(name="App").client_id
    client_secret = Application.objects.get(name="App").client_secret
    #redirect_uri = request.GET.get("redirect_uri", "http://test.com:8002/callback")
    redirect_uri = request.GET.get("redirect_uri", "http://test.com:8002/unique_redirect.html")
    
    data = {
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri": redirect_uri,
        "client_id": client_id,
        "client_secret": client_secret,
    }
    
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': f'Basic {base64.b64encode(f"{client_id}:{client_secret}".encode()).decode()}',
    }
    
    response = requests.post(token_url, data=data, headers=headers)
    tokens = response.json()
    print(tokens)
    if response.status_code != 200:
        return JsonResponse({'error': 'token_exchange_failed', 'details': tokens}, status=response.status_code)
    
    request.session['access_token'] = tokens['access_token']
    request.session['refresh_token'] = tokens['refresh_token']
    
    return JsonResponse(tokens)
   #return redirect('profile')

问题是,如果我使用超级用户凭据登录 OAuth 2.0 管理面板,则上述代码可以正常工作并重定向到提供的 URL。否则它不起作用并使用 LOGIN_REDIRECT_URL = '/profile/' from settings.py

可能是什么原因?


The issue you are facing is related to how Django OAuth Toolkit handles redirect URIs and its interaction with the Django authentication system.

Here's a breakdown of why the code works with a superuser but not with regular users and how to fix it:

The Problem:

  • Conflicting Redirects: When you log in as a superuser, you're likely already authenticated in the Django admin panel. In this case, Django OAuth Toolkit probably bypasses its internal redirect mechanism since you have an active session. It directly uses the redirect_uri provided in your oauth_callback view.

  • LOGIN_REDIRECT_URL Interference: For non-superuser logins, Django's authentication system kicks in. After a successful OAuth flow, Django sees that the user is now authenticated but doesn't have session data to determine where they should be redirected. This is when it defaults to the LOGIN_REDIRECT_URL specified in your settings.py .

The Solution:

You can address this problem in a couple of ways:

1. Consistent Redirect Handling within oauth_callback :

  • Store Redirect URI in Session: Before redirecting to the authorization URL in oauth_login , store the intended redirect_uri in the session:

    python def oauth_login(request): # ... your code ... request.session['oauth_redirect_uri'] = redirect_uri authorization_url = ( f"http://test.com:8000/o/authorize/?client_id={app.client_id}" f"&response_type=code&redirect_uri={redirect_uri}" ) return redirect(authorization_url)

  • Retrieve and Redirect: After successful token exchange in oauth_callback , retrieve the stored redirect URI and redirect the user:

    ```python def oauth_callback(request): # ... your code ...

     redirect_uri = request.session.get('oauth_redirect_uri', '/')  # Get from session
     del request.session['oauth_redirect_uri']  # Clear from session
    
     return redirect(redirect_uri)
    

    ```

2. Leverage Django OAuth Toolkit's Redirect URI Validation:

  • Whitelist Redirect URIs: In your OAuth application settings (either through the admin interface or programmatically), explicitly define a list of allowed redirect URIs for your application.
  • Dynamic Redirect URI Parameter: Django OAuth Toolkit may support a parameter (e.g., state ) that you can pass in the authorization URL to store the redirect URI. This value will be passed back to your oauth_callback for secure redirection.

Additional Considerations:

  • Security: Always validate the redirect URIs received from the client-side to prevent open redirects, which can lead to security vulnerabilities.
  • Error Handling: Implement proper error handling for cases where the OAuth flow fails (e.g., invalid code, token exchange errors). Display user-friendly error messages and log the details for debugging.

By implementing one of these solutions, you can ensure that your OAuth flow correctly redirects users to the intended location, regardless of whether they are a superuser or a regular user.

标签:python,django,session,django-oauth,django-oauth-toolkit
From: 78796237

相关文章

  • Python 教程(三):字符串特性大全
    目录专栏列表前言1.字符串基础2.字符串方法字符串查询字符串修改字符串切片3.字符串格式化旧式格式化(`%`操作符)`str.format()`方法f-string(Python3.6+)4.字符串编码5.Unicode和ASCII6.正则表达式7.字符串比较8.字符串连接9.字符串不可变性10.字符串的内......
  • python+flask计算机毕业设计新冠肺炎疫情人员统计及打卡系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景自新冠肺炎疫情爆发以来,全球公共卫生体系面临前所未有的挑战。疫情防控工作的高效开展,依赖于对人员流动、健康状况及疫情数据的精准掌握与......
  • python+flask计算机毕业设计基于智能匹配的体育场馆预约系统App(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着全民健身意识的日益增强,体育场馆作为民众参与体育活动的重要场所,其利用率与便捷性成为了社会关注的焦点。然而,传统的体育场馆预约方式......
  • Vonage 语音 API - 使用 python 出现错误
    我正在尝试使用vonage语音api模拟语音通话。我正在尝试使用python来做到这一点。我创建了一个.env文件并更新了应用程序id和私钥值的值,而不是路径(不确定从哪里获取它)。这是下面编写的代码:#!/usr/bin/envpython3importosfromos.pathimportjoin,dirname......
  • 数据清洗与预处理:使用 Python Pandas 库
    数据清洗与预处理:使用PythonPandas库1.简介数据清洗与预处理是数据科学和机器学习中必不可少的步骤。它涉及识别和处理原始数据中的错误、不一致和缺失值,以确保数据的质量和可靠性。Python的Pandas库提供了强大的工具,简化了数据清洗和预处理的过程。2.数据加载与探索......
  • 【Python】成功解决:`FileExistsError: [Errno 17] File exists: ‘xxx’`
    【Python】成功解决:FileExistsError:[Errno17]Fileexists:‘xxx’在Python编程中,处理文件和目录是常见的任务之一。然而,当我们尝试执行某些文件操作,如创建新文件或目录时,如果目标文件或目录已经存在,就可能会遇到FileExistsError异常。这个错误通常伴随着消息[Errno1......
  • 计算机毕业设计django+vueblockly少儿编程在线学习网站【开题+论文+程序】
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在数字化教育日益普及的今天,少儿编程教育作为培养学生逻辑思维、创造力和解决问题能力的重要手段,正受到越来越多的关注和重视。然而,传统的......
  • 计算机毕业设计django+vueee家教管理系统【开题+论文+程序】
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着教育市场的不断扩展和个性化学习需求的日益增长,家教服务作为一种灵活高效的教育补充形式,受到了广大学生及家长的青睐。然而,传统的家教......
  • (三)Python基本数据类型
    Python的基本数据类型包括整数类型、浮点数类型和复数类型。下面分别介绍这些数据类型以及数值运算操作符和数值运算函数。整数类型(int):整数类型表示没有小数部分的数字,可以是正数、负数或零。例如:a=5b=-3c=02.浮点数类型(float):浮点数类型表示有小数部分的数字,可以......
  • 【Python自动化办公】用Pandas库自动化操作Excel表格,从读取、写入到数据处理和分析
    文末免费赠送精品编程资料~~前言Python的第三方Pandas库是数据处理和分析中的利器,其强大的功能可以帮助我们轻松地对Excel表格进行自动化操作。接下来,我们将介绍九个用Pandas库操作Excel的编程例子,并且每个例子都会涉及不同的知识点,确保全面掌握这个主题。1.读取和写入E......