Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Django OAuth2 和 JWT 案例

Django OAuth2 和 JWT 案例

作者头像
用户1416054
发布于 2018-08-02 03:44:40
发布于 2018-08-02 03:44:40
1.4K00
代码可运行
举报
文章被收录于专栏:JackeyGao的博客JackeyGao的博客
运行总次数:0
代码可运行

Django OAuth2 和 JWT 案例

Posted August 08, 2017

在重写 Ansible 监控平台时, 需要前后端分离, 并且需要使用公司的账户系统。 而前后端认证我一直采取的 JWT 认证规范,具体为什么这么选择, 这里不多讲。而符合DRF 的JWT 框架, 默认使用的是 Django 自带的账户系统做的。 所以再 OAuth2 和 JWT 结合需要做点工作。

OAuth2认证方法

此步骤主要包含, 从资源服务器交换 Token, 然后根据 token 获取当前用户的 profile 信息, 一般为 email 和 avatar 信息. 然后创建 Django 自带的 User。 也可以通过函数实现。

Python

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-

"""
web.auth
~~~~~~~~

Cable 认证组件

这里只接受 code, 通过 code 及相对应的密钥换取 Token 后

获取用户信息, 并根据数据库是否有此用户。

如果没有此用户则创建, 并设置未激活状态

如果有此用户, 并且处于未激活状态, 则提示用户找管理员激活

如果已经激活, 返回登录此用户并返回 jwt.
"""

import requests
from web.models import Profile
from web.models import User
from rest_framework.exceptions import APIException


class TeambitionAuthenticationFailed(APIException):
    status_code = 401
    default_code = 'Unauthorized'


class CableOAuth2(object):

    access_token_url = "https://account.teambition.com/oauth2/access_token"
    user_profile_url = "https://api.teambition.com/api/users/me"

    def __init__(self, CK, SK):
        self.CK = CK
        self.SK = SK

    def get_profile(self, email=""):
        profile = Profile.objects.filter(user__email=email).first()

        return profile

    def get_user(self, email=""):
        user = User.objects.filter(email=email).first()

        return user

    def is_actived(self, user):
        return user.is_active

    def get_access_token(self, code):
        payload = {
            'client_id': self.CK,
            'client_secret': self.SK,
            'code': code,
            'grant_type': 'Bearer'
        }

        resp = self.request(
            "POST",
            self.access_token_url,
            data=payload
        )

        data = resp.json()
        return data.get('access_token', None)

    def get_me(self, access_token):
        """
        获取用户信息
        """
        resp = self.request(
            "GET",
            self.user_profile_url + '?access_token=' + access_token
        )

        return resp.json()

    def request(self, method, url, **kwargs):
        resp = requests.request(method, url, **kwargs)

        try:
            resp.raise_for_status()
        except requests.HTTPError as e:
            m = resp.json()

            detail = "%s %s" % (url, str(e))
            if 'message' in m and 'name' in m:
                detail = "%s %s" % (m["name"], m["message"])

            raise TeambitionAuthenticationFailed(detail)
        return resp

    def authentication(self, code):
        access_token = self.get_access_token(code)

        # 如果没有获取到 access token 那么后面就不继续了
        # 直接报错给客户端
        if not access_token:
            detail = "Get access token failure"
            raise TeambitionAuthenticationFailed(detail)

        me = self.get_me(access_token)

        # 这里做下安全保护, 如果非 teambition 域名的用户
        # 直接返回, 并给出非法警告.
        if not me["email"].endswith('teambition.com'):
            detail = "非法操作, 您不是 teambtion 员工,请立即停止此行为!!"
            raise TeambitionAuthenticationFailed(detail)

        user = self.get_user(me["email"])
        profile = self.get_profile(me["email"])

        if not user:
            user = User(
                username=me["email"].split("@")[0],
                email=me["email"],
                is_active=False
            )

            user.save()

        profile_data = {
            "avatar": me["avatarUrl"]
        }

        Profile.objects.update_or_create(user=user, defaults=profile_data)

        return user

JWT APIView*

引入的包

Python

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from django.utils.translation import ugettext as _
from rest_framework_jwt.serializers import JSONWebTokenSerializer
from rest_framework_jwt.serializers import Serializer
from rest_framework_jwt.serializers import jwt_payload_handler
from rest_framework_jwt.serializers import jwt_encode_handler
from rest_framework_jwt.serializers import jwt_decode_handler
from rest_framework_jwt.serializers import jwt_get_username_from_payload
from rest_framework_jwt.views import JSONWebTokenAPIView
from rest_framework_jwt.views import jwt_response_payload_handler
from rest_framework_jwt.settings import api_settings
from rest_framework import serializers
from rest_framework import status
from rest_framework.response import Response
from django.conf import settings
from web.auth import CableOAuth2

由于 OAuth2 返回时仅返回 code, 所以需要在JWTSerializer中获取此 code 并通过上面方法认证.

Python

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class TeambitionJWTSerializer(Serializer):

    def validate(self, attrs):
        code = self.initial_data.get("code", None)

        oa = CableOAuth2(CK=settings.OAUTH_CLIENT_KEY, SK=settings.OAUTH_SECRET_KEY)

        user = oa.authentication(code)

        if user:
            if not user.is_active:
                msg = _('User account is not actived or 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)

默认的 JWT APIView 方法是 POST, OAuth2 Callback URL 是 GET 方式, 所以需要自定义个JWTView, 目的是通过回调ˇ GET 的方式获得 Code.

Python

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class TeambitionJWTAPIView(JSONWebTokenAPIView):

    def get(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.GET)

        if serializer.is_valid():
            user = serializer.object.get('user') or request.user
            token = serializer.object.get('token')
            response_data = jwt_response_payload_handler(token, user, request)
            response = Response(response_data)
            if api_settings.JWT_AUTH_COOKIE:
                expiration = (datetime.utcnow() +
                              api_settings.JWT_EXPIRATION_DELTA)
                response.set_cookie(api_settings.JWT_AUTH_COOKIE,
                                    token,
                                    expires=expiration,
                                    httponly=True)
            return response

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

绑定到 Serializer

Raw

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class TeambitionObtainJSONWebToken(TeambitionJWTAPIView):
    serializer_class = TeambitionJWTSerializer


teambition_obtain_jwt_token = TeambitionObtainJSONWebToken.as_view()

替换默认的签发路径

并把资源服务的应用程序回掉地址改为http://<host:port>/jwt/teambition/obtain

Python

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from django.conf.urls import url, include
from web.auth.jwt import teambition_obtain_jwt_token
from rest_framework_jwt.views import obtain_jwt_token
from rest_framework_jwt.views import refresh_jwt_token
from rest_framework_jwt.views import verify_jwt_token


urlpatterns = [
    # oauth2 
    url(r'^jwt/teambition/obtain', teambition_obtain_jwt_token),

    # username & password auth
    # url(r'^jwt/obtain', obtain_jwt_token),
    url(r'^jwt/refresh', refresh_jwt_token),
    url(r'^jwt/verify', verify_jwt_token),
]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Service Mesh - Istio服务观测篇
Kiali属于Istio的集成组件之一,是一个用于Istio的可观测性控制台,具有服务网格配置和验证功能。它通过监控网络流量来推断服务拓扑和报告错误,帮助你了解服务网格的结构和运行状况。Kiali提供了详细的度量和基本的Grafana集成,可用于高级查询。
端碗吹水
2020/12/28
1K0
Service Mesh - Istio服务观测篇
Isito 入门(四):微服务可观测性
Istio 集成了 Jaeger、Zipkin 和 Skywalking 等链路追踪应用,能够有效地捕获服务网格的结构,展示网络拓扑结构,并分析网格的健康状况。
痴者工良
2023/07/24
4690
Isito 入门(四):微服务可观测性
Istio服务网格的可观察性
前面我们学习了 Istio 中的流量管理功能,本节我们来学习如何配置 Istio来自动收集网格中的服务遥测。Istio为网格内所有的服务通信生成详细的遥测数据,这种遥测技术提供了服务的可观察性,使运维人员能够排查故障、维护和优化应用程序,而不会给服务的开发人员带来任何额外的负担。通过 Istio,运维人员可以全面了解到受监控的服务如何与其他服务以及Istio组件进行交互。
王先森sec
2023/04/24
9060
Istio服务网格的可观察性
服务网格简介
了解服务网格如何通过 Istio 和 Linkerd 等解决方案改进微服务的安全性、流量管理和可观测性。
云云众生s
2025/03/01
1440
OpenTelemetry:Go可观测性指南
现代应用程序通常是复杂的分布式系统。调试它们可不是一件有趣的事情:你必须跟踪跨服务的请求,日志会丢失,而且指标通常难以关联。这就像大海捞针——只不过这个草堆正在燃烧,而且针还在移动。这就是 OpenTelemetry (OTel) 可以提供帮助的地方。
云云众生s
2025/02/09
1520
OpenTelemetry:Go可观测性指南
在服务网格环境下实现微服务的可观测性与诊断能力!
在现代分布式系统中,微服务架构已成为一种主流的开发模式。随着业务规模的扩大,服务间的通信、故障排查以及性能监控变得越来越复杂。传统的监控方式无法满足日益复杂的需求,这时候,服务网格(如 Istio、Linkerd 等)应运而生,提供了强大的流量管理、故障隔离、追踪与监控能力。而在这些功能中,可观测性与诊断能力无疑是最为关键的部分。
bug菌
2025/02/21
1160
在服务网格环境下实现微服务的可观测性与诊断能力!
基于 eBPF 的云原生可观测性深度实践
本文整理自云杉网络 DeepFlow 产品负责人向阳在 QCon 2023 的演讲分享,主题为“基于 eBPF 的云原生可观测性深度实践”。
从大数据到人工智能
2023/04/18
1.3K2
基于 eBPF 的云原生可观测性深度实践
Istio多集群链路追踪实践
为了实现多集群的流量治理,我们采用Istio官方提供的多主集群进行Istio的部署,这样就出现一个问题,对于多主集群的Istio治理,如何进行跨集群的流量监控,实现跨集群的服务链路追踪。
CNCF
2022/11/28
1.1K0
Istio多集群链路追踪实践
【译文连载】 理解Istio服务网格(第六章 可观测性)
微服务架构管理中最大的挑战之一是如何通过简单方法就能了解系统各个组件之间的关系。终端用户的一次会话可能会流经多个甚至几十个独立部署的微服务,因此,发现哪里有性能瓶颈或错误变得尤为重要。
SammyLiu
2020/03/11
9140
Istio服务网格:为忙碌人士而生
我最近为 Istio 做出了一个小贡献,Istio 是一个开源服务网格项目。我的贡献包括为 Istio CLI 的一个命令添加了一些测试。如果你想查看详细信息,可以在 此处 找到 pull 请求。这不是一个巨大的改变,但它是一个很棒的学习体验。在 Istio 上工作帮助我更深入地理解了服务网格。我很高兴能做出更多贡献。在这篇文章中,我将解释什么是 Istio,它为什么有用以及它是如何工作的。
云云众生s
2024/09/27
1950
云原生环境中可观测性日益增长的重要性
云原生可观测性迎来AI驱动时代!预测性监控、异常检测助力快速定位问题。拥抱OpenTelemetry标准化遥测数据,降低运营成本。DevSecOps融合安全与可观测性,FinOps实现成本优化。未来可观测性将更智能、更安全、更经济!
云云众生s
2025/03/17
780
实现全托管,腾讯云服务网格的架构演进
|导语 腾讯云服务网格(TCM)作为一个兼容 isito 的服务网格平台,已经在腾讯内外部有诸多落地案例。本文深度解析服务网格架构演进和发展趋势。 一、 istio 现状和发展趋势 1. istio发展现状 istio现在是目前最流行的服务网格实现,它的流行主要体现在两个方面。 一是社区非常的活跃,过去一年,Istio 在 GitHub 增长最快的开源项目排行榜上名列第四。 另一方面 istio 在业界有了越来越多的生产落地。在一项云原生调研报告中,已经有18% 的用户在生产环境中使用mesh 技术,
腾讯大讲堂
2020/10/09
2.2K0
五分钟了解 KubeGems 可观测性
可观测性 Observability 是近几年来随着应用微服务和容器化推进而引领出来的一个概念。其提出的最核心的三个方向 Monitoring 、Logging 和 Tracing 目前也已广泛的被各从业人员和SaaS 服务商接受,并应用在项目当中。当下具备一个可观测性分析的平台以及作为云原生时代微服务系统基础组件,不管是从 CNCF 社区还是公有云平台开放性与性能是决定平台价值的核心要素。在复杂的微服务场景下和多维度的监控数据,对 KubeGems 的可观测性设计实现带了诸多挑战。本次分享也从一个使用者的角度快速介绍当前 KubeGems 可观测性的功能。
云原生小白
2022/11/11
8460
五分钟了解 KubeGems 可观测性
Istio面试题及答案-2023&2024
Istio基于Envoy代理实现服务网格的功能,通过Pilot进行配置管理,Mixer进行遥测和策略执行,Citadel提供安全控制,Galley负责校验和转换配置资源,Ingress Gateway提供对Kubernetes集群内部服务的访问。这些组件共同构成了Istio的控制平面和数据平面。
jack.yang
2025/04/05
790
Istio面试题及答案-2023&2024
Istio可观测性
Istio的可观测性包括metrics,日志,分布式链路跟踪以及可视化展示。下面主要介绍如何在istio中部署基于Prometheus的metrics监控,基于jaeger的链路跟踪和基于kiali的可视化界面。
charlieroro
2020/09/07
2.9K0
Kubernetes 上的服务网格技术大比较: Istio, Linkerd 和 Consul
云原生应用通常是由一组运行在容器中的分布式微服务架构起来的。目前越来越多的容器应用都是基于 Kubernetes 的,Kubernetes 已经成为了容器编排的事实标准。
黑光技术
2020/05/14
3.2K0
Kubernetes 上的服务网格技术大比较: Istio, Linkerd 和 Consul
Nacos架构与原理 -服务网格生态
要深入理解服务网格的概念,明确服务网格要解决的问题,以及认识服务网格带来的业务价值,需要从应用架构的演进发展从头开始讲起。
小小工匠
2023/07/11
1.2K0
Nacos架构与原理 -服务网格生态
微服务网格化升级后的安全架构问题
2016 年 9 月 14 日,Envoy 的开源标志着应用技术架构进入到服务网格(Service Mesh)时代,2017 年 5 月 24 日,Google、IBM、Lyft 共同宣布 Istio 开源标志着进入由控制面和数据面组成的服务网格成为主流。Istio 是当前最受欢迎的服务网格技术。
腾讯金融安全
2024/11/27
1370
微服务网格化升级后的安全架构问题
Istio架构、技术栈及适用场景
Istio 是一个开源的服务网格(Service Mesh)平台,设计用于简化微服务架构中的服务间通信和服务管理。其架构主要分为两个核心部分:控制平面(Control Plane)和数据平面(Data Plane)。
用户7353950
2024/06/18
3970
Istio架构、技术栈及适用场景
从Service Mesh谈如何做好监控
谈到 Service Mesh,人们总是想起微服务和服务治理,从 Dubbo 到 Spring Cloud (2016开始进入国内研发的视野,2017年繁荣)再到 Service Mesh (2018年开始被大家所熟悉),正所谓长江后浪推前浪,作为后浪,Service Mesh 别无选择,而 Spring Cloud 对 Service Mesh 满怀羡慕,微服务架构的出现与繁荣,是互联网时代架构形式的巨大突破。Service Mesh 具有一定的学习成本,实际上在国内的落地案例不多,大多是云商与头部企业,随着性能与生态的完善以及各大社区推动容器化场景的落地,Service Mesh 也开始在大小公司生根发芽,弥补容器层与 Kubernetes 在服务治理方面的短缺之处。本次将以一个选型调研者的视角,来看看 Service Mesh 中的可观察性主流实践方案。
用户5397975
2020/06/04
1.3K0
从Service Mesh谈如何做好监控
推荐阅读
相关推荐
Service Mesh - Istio服务观测篇
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验