f5327d6b by 周伟奇

add iwa logiin

1 parent 3d620b3b
......@@ -4,4 +4,6 @@ from . import views
urlpatterns = [
path(r'login/', views.LoginView.as_view()),
path(r'iwalogin/', views.IWALoginView.as_view()),
path(r'iwaurl/', views.IWAUrlView.as_view()),
]
......
from common.mixins import GenericView
import base64
from common.mixins import GenericView, IWABaseView
from rest_framework import status
from rest_framework_jwt.views import ObtainJSONWebToken
from common import response
from common.redis_cache import redis_handler as rh
from .consts import LOGIN_TIMES_LIMIT_EXPIRES, LOGIN_TIMES_LIMIT
from settings import conf
# Create your views here.
# https://auth-i.bmwgroup.net/auth/oauth2/intranetb2x/
iwa_url_params = {
'scope': 'openid',
'response_type': 'code',
'redirect_uri': conf.REDIRECT_URI,
'client_id': conf.IWA_CLIENT_ID
}
iwa_url_params_str = '&'.join(['{0}={1}'.format(k, v) for k, v in iwa_url_params])
iwa_url = '{0}authorize?{1}'.format(conf.IWA_URL, iwa_url_params_str)
client_id_base64 = base64.b64encode('{0}:{1}'.format(
conf.IWA_CLIENT_ID, conf.IWA_CLIENT_SECRET).encode('utf-8')).decode('utf-8')
class LoginView(ObtainJSONWebToken, GenericView):
......@@ -32,3 +46,27 @@ class LoginView(ObtainJSONWebToken, GenericView):
'token': res.data.get('token'),
}
return response.ok(data=data)
class IWALoginView(IWABaseView, GenericView):
def post(self, request, *args, **kwargs):
code = request.data.get('code', '')
redirect_uri = request.data.get('redirect_uri', '')
q_number = self.get_q_number(conf.IWA_URL, code, redirect_uri, client_id_base64)
is_valid, data = self.validate(q_number)
if is_valid:
return response.ok(data=data)
else:
self.no_permission(data)
class IWAUrlView(IWABaseView, GenericView):
def get(self, request, *args, **kwargs):
data = {
'iwa_url': iwa_url,
}
return response.ok(data=data)
......
import logging
import requests
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from rest_framework.generics import GenericAPIView
from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler
from common.exceptions import (
NeedLoginException,
InvalidParamsException,
......@@ -100,3 +103,59 @@ class GenericView(LoggerMixin, GenericExceptionMixin, GenericAPIView):
def get_object(self):
return None
class IWABaseView:
# def __init__(self):
# self.iwa_url_base = 'https://auth-i.bmwgroup.net/auth/oauth2/intranetb2x/'
@staticmethod
def get_token(iwa_url_base, code, redirect_uri, client_id_base64):
headers = {
'authorization': 'Basic {0}'.format(client_id_base64), # client_id:secret做base64encode
'content-type': 'application/x-www-form-urlencoded',
}
get_params_dict = {
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': redirect_uri,
}
get_params_str = '&'.join(['{0}={1}'.format(k, v) for k, v in get_params_dict])
iwa_token_url = '{0}access_token?{1}'.format(iwa_url_base, get_params_str)
res = requests.post(iwa_token_url, headers=headers)
return res.json().get('access_token', '')
def get_q_number(self, iwa_url_base, code, redirect_uri, client_id_base64):
access_token = self.get_token(iwa_url_base, code, redirect_uri, client_id_base64)
headers = {
'authorization', 'Bearer {0}'.format(access_token)
}
iwa_user_url = '{0}userinfo'.format(iwa_url_base)
res = requests.get(iwa_user_url, headers=headers)
return res.json().get('sub', '')
@staticmethod
def validate(q_number):
if not q_number:
return False, 'get q_number empty'
user = get_user_model().objects.filter(username=q_number).first()
if user:
if not user.is_active:
msg = 'User account is disabled.'
return False, msg
payload = jwt_payload_handler(user)
user_info = {
'user_id': user.id,
'user_name': user.username,
'token': jwt_encode_handler(payload),
}
return True, user_info
else:
msg = 'q_number user not found'
return False, msg
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!