639ea2eb by 周伟奇

add OAuth

1 parent 5731e2bd
...@@ -11,6 +11,8 @@ tags: ...@@ -11,6 +11,8 @@ tags:
11 schemes: 11 schemes:
12 - https 12 - https
13 - http 13 - http
14 security:
15 - OAuth2: []
14 paths: 16 paths:
15 /api/create/v1: 17 /api/create/v1:
16 post: 18 post:
...@@ -32,6 +34,43 @@ paths: ...@@ -32,6 +34,43 @@ paths:
32 description: ok 34 description: ok
33 schema: 35 schema:
34 $ref: '#/definitions/ApiResponse' 36 $ref: '#/definitions/ApiResponse'
37 /api/priority/v1:
38 post:
39 tags:
40 - doc
41 summary: GCAP提高申请单对应文件优先级
42 consumes:
43 - application/json
44 produces:
45 - application/json
46 parameters:
47 - in: body
48 name: body
49 required: true
50 schema:
51 $ref: '#/definitions/Application'
52 responses:
53 200:
54 description: ok
55 schema:
56 $ref: '#/definitions/ApiResponse'
57 securityDefinitions:
58 OAuth2:
59 type: oauth2
60 flow: application
61 description: 'This API uses OAuth 2 with the application(clientCredentials) grant
62 flow.
63
64 client_id=sMlciTkppsMzARwHpCVarm5q7DP2Vucj3ny8JFhw
65
66 client_secret=WNoOilDx140ZLcenDKfsnikv7S2LIFs60DciYoqnrZaYLqYsKpcmt7mJIL69o9AEf84uQvRnS3K2UioxfjNyImjR4UOyXbDcF6qYgTLC4KDVByKFdVhKfrn2Lc4q4BNW
67
68 scopes=write
69
70 '
71 tokenUrl: https://staging-bmw-ocr.situdata.com/api/oauth/token/
72 scopes:
73 write: Grants write access
35 responses: 74 responses:
36 ErrorResponse: 75 ErrorResponse:
37 description: 调用异常, 具体情况请参考`HTTP`状态码和`code`字段 76 description: 调用异常, 具体情况请参考`HTTP`状态码和`code`字段
...@@ -130,6 +169,54 @@ definitions: ...@@ -130,6 +169,54 @@ definitions:
130 description: 元数据版本ID 169 description: 元数据版本ID
131 type: string 170 type: string
132 example: '8410480' 171 example: '8410480'
172 Application:
173 type: object
174 required:
175 - APPLICATION_INFORMATION
176 properties:
177 APPLICATION_INFORMATION:
178 description: 申请单信息
179 type: object
180 required:
181 - SUBMIT_DATETIME
182 - STATUS
183 - ENTITY
184 - RATING
185 - APPLICATION_ID
186 - APPLICATION_VERSION
187 - INTERMEDIATE_DECISION
188 properties:
189 SUBMIT_DATETIME:
190 description: 提交时间
191 type: string
192 example: 2020-07-08 18:33:31+08:00
193 STATUS:
194 description: 状态
195 type: integer
196 example: 42
197 ENTITY:
198 description: 业务类型
199 type: string
200 example: CO00001
201 enum:
202 - CO00001
203 - CO00002
204 RATING:
205 description: 排名
206 type: integer
207 example: 4
208 APPLICATION_ID:
209 description: 申请id
210 type: string
211 example: CH-B0011010101
212 APPLICATION_VERSION:
213 description: 申请版本
214 type: integer
215 example: 1
216 INTERMEDIATE_DECISION:
217 description: ''
218 type: string
219 example: MUW
133 ApiResponse: 220 ApiResponse:
134 description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容 221 description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容
135 type: object 222 type: object
......
...@@ -9,6 +9,7 @@ certifi==2020.6.20 ...@@ -9,6 +9,7 @@ certifi==2020.6.20
9 chardet==3.0.4 9 chardet==3.0.4
10 defusedxml==0.6.0 10 defusedxml==0.6.0
11 Django==2.1 11 Django==2.1
12 django-oauth-toolkit==1.3.2
12 djangorestframework==3.9.0 13 djangorestframework==3.9.0
13 djangorestframework-jwt==1.11.0 14 djangorestframework-jwt==1.11.0
14 idna==2.9 15 idna==2.9
...@@ -17,6 +18,7 @@ isodate==0.6.0 ...@@ -17,6 +18,7 @@ isodate==0.6.0
17 lxml==4.5.1 18 lxml==4.5.1
18 marshmallow==3.6.1 19 marshmallow==3.6.1
19 multidict==4.7.6 20 multidict==4.7.6
21 oauthlib==3.1.0
20 pdfminer3k==1.3.4 22 pdfminer3k==1.3.4
21 Pillow==7.1.2 23 Pillow==7.1.2
22 ply==3.11 24 ply==3.11
......
1 from django.contrib.auth import get_user_model
2 from oauth2_provider.contrib.rest_framework import OAuth2Authentication
3 from oauth2_provider.oauth2_backends import get_oauthlib_core
4
5
6 class OAuth2AuthenticationWithUser(OAuth2Authentication):
7 """
8 OAuth 2 authentication backend using `django-oauth-toolkit`
9 """
10 www_authenticate_realm = "api"
11 user = get_user_model().objects.first()
12
13 def authenticate(self, request):
14 """
15 Returns two-tuple of (user, token) if authentication succeeds,
16 or None otherwise.
17 """
18 oauthlib_core = get_oauthlib_core()
19 valid, r = oauthlib_core.verify_request(request, scopes=[])
20 if valid:
21 return self.user, r.access_token
22 request.oauth2_error = getattr(r, "oauth2_error", {})
23 return None
1 import os
2 import fitz
3 import signal
4 from PIL import Image
5 from io import BytesIO
6
7 from django.core.management import BaseCommand
8 from common.mixins import LoggerMixin
9
10
11 class Command(BaseCommand, LoggerMixin):
12
13 def __init__(self):
14 super().__init__()
15 self.log_base = '[pdf to img]'
16 # 处理文件开关
17 self.switch = True
18 # pdf页面转图片
19 self.zoom_x = 2.0
20 self.zoom_y = 2.0
21 self.trans = fitz.Matrix(self.zoom_x, self.zoom_y).preRotate(0) # zoom factor 2 in each dimension
22 # 优雅退出信号:15
23 signal.signal(signal.SIGTERM, self.signal_handler)
24
25 def signal_handler(self, sig, frame):
26 self.switch = False # 停止处理文件
27
28 @staticmethod
29 def getimage(pix):
30 if pix.colorspace.n != 4:
31 return pix
32 tpix = fitz.Pixmap(fitz.csRGB, pix)
33 return tpix
34
35 def recoverpix(self, doc, item):
36 x = item[0] # xref of PDF image
37 s = item[1] # xref of its /SMask
38 is_rgb = True if item[5] == 'DeviceRGB' else False
39
40 # RGB
41 if is_rgb:
42 if s == 0:
43 return doc.extractImage(x)
44 # we need to reconstruct the alpha channel with the smask
45 pix1 = fitz.Pixmap(doc, x)
46 pix2 = fitz.Pixmap(doc, s) # create pixmap of the /SMask entry
47
48 # sanity check
49 if not (pix1.irect == pix2.irect and pix1.alpha == pix2.alpha == 0 and pix2.n == 1):
50 pix2 = None
51 return self.getimage(pix1)
52
53 pix = fitz.Pixmap(pix1) # copy of pix1, alpha channel added
54 pix.setAlpha(pix2.samples) # treat pix2.samples as alpha value
55 pix1 = pix2 = None # free temp pixmaps
56 return self.getimage(pix)
57
58 # GRAY/CMYK
59 pix1 = fitz.Pixmap(doc, x)
60 pix = fitz.Pixmap(pix1) # copy of pix1, alpha channel added
61
62 if s != 0:
63 pix2 = fitz.Pixmap(doc, s) # create pixmap of the /SMask entry
64
65 # sanity check
66 if not (pix1.irect == pix2.irect and pix1.alpha == pix2.alpha == 0 and pix2.n == 1):
67 pix2 = None
68 return self.getimage(pix1)
69
70 pix.setAlpha(pix2.samples) # treat pix2.samples as alpha value
71
72 pix1 = pix2 = None # free temp pixmaps
73
74 pix = fitz.Pixmap(fitz.csRGB, pix) # GRAY/CMYK to RGB
75 return self.getimage(pix)
76
77 @staticmethod
78 def get_img_data(pix):
79 if type(pix) is dict: # we got a raw image
80 ext = pix["ext"]
81 img_data = pix["image"]
82 else: # we got a pixmap
83 ext = 'png'
84 img_data = pix.getPNGData()
85 return ext, img_data
86
87 @staticmethod
88 def split_il(il):
89 img_il_list = []
90 start = 0
91 length = len(il)
92 for i in range(length):
93 if i == start:
94 if i == length - 1:
95 img_il_list.append(il[start: length])
96 continue
97 elif i == length - 1:
98 img_il_list.append(il[start: length])
99 continue
100 if il[i][2] != il[i - 1][2]:
101 img_il_list.append(il[start: i])
102 start = i
103 elif il[i][3] != il[i - 1][3]:
104 img_il_list.append(il[start: i + 1])
105 start = i + 1
106 return img_il_list
107
108 def handle(self, *args, **kwargs):
109 pdf_dir = '/Users/clay/Desktop/普通打印-部分无线/竖版-无表格-农业银行'
110 img_dir = '/Users/clay/Desktop/普通打印-部分无线_img/竖版-无表格-农业银行'
111 os.makedirs(img_dir, exist_ok=True)
112 for d in os.listdir(pdf_dir):
113 # if d in ['.DS_Store', 'CH-B008486764.pdf', 'CH-B008003736.pdf', 'CH-B008487476.pdf', 'CH-B006763780.pdf',
114 # 'CH-B009000564.pdf', 'CH-B009020488.pdf']:
115 if d in ['.DS_Store', '1竖版-无表格-农业银行样例.PNG']:
116 continue
117 pdf_path = os.path.join(pdf_dir, d)
118 # pdf_path = '/Users/clay/Desktop/普通打印part2/工商银行(标准版)/CH-B006754676.pdf'
119 if os.path.isfile(pdf_path):
120 img_save_path = os.path.join(img_dir, d)
121 if os.path.exists(img_save_path):
122 continue
123 os.makedirs(img_save_path, exist_ok=True)
124 with fitz.Document(pdf_path) as pdf:
125 self.cronjob_log.info('{0} [pdf_path={1}] [metadata={2}]'.format(
126 self.log_base, pdf_path, pdf.metadata))
127 # xref_list = []
128 for pno in range(pdf.pageCount):
129 il = pdf.getPageImageList(pno)
130 il.sort(key=lambda x: x[0])
131 img_il_list = self.split_il(il)
132 del il
133
134 print(img_il_list)
135 if len(img_il_list) > 3: # 单页无规律小图过多时,使用页面转图片
136 page = pdf.loadPage(pno)
137 pm = page.getPixmap(matrix=self.trans, alpha=False)
138 save_path = os.path.join(img_save_path, 'page_{0}_img_0.png'.format(page.number))
139 pm.writePNG(save_path)
140 # img_path_list.append(save_path)
141 # self.cronjob_log.info('{0} [page to img success] [doc_id={1}] [pdf_path={2}] '
142 # '[page={3}]'.format(self.log_base, doc_id, pdf_path, page.number))
143 else: # 提取图片
144 for img_index, img_il in enumerate(img_il_list):
145 if len(img_il) == 1: # 当只有一张图片时, 简化处理
146 pix = self.recoverpix(pdf, img_il[0])
147 ext, img_data = self.get_img_data(pix)
148 save_path = os.path.join(img_save_path, 'page_{0}_img_{1}.{2}'.format(
149 pno, img_index, ext))
150 with open(save_path, "wb") as f:
151 f.write(img_data)
152 # img_path_list.append(save_path)
153 # self.cronjob_log.info(
154 # '{0} [extract img success] [doc_id={1}] [pdf_path={2}] [page={3}] '
155 # '[img_index={4}]'.format(self.log_base, doc_id, pdf_path, pno, img_index))
156 else: # 多张图片,竖向拼接
157 height_sum = 0
158 im_list = []
159 width = img_il[0][2]
160 for img in img_il:
161 # xref = img[0]
162 # if xref in xref_list:
163 # continue
164 height = img[3]
165 pix = self.recoverpix(pdf, img)
166 ext, img_data = self.get_img_data(pix)
167
168 # xref_list.append(xref)
169
170 im = Image.open(BytesIO(img_data))
171 im_list.append((height, im, ext))
172 height_sum += height
173
174 save_path = os.path.join(img_save_path, 'page_{0}_img_{1}.{2}'.format(
175 pno, img_index, im_list[0][2]))
176 res = Image.new(im_list[0][1].mode, (width, height_sum))
177 h_now = 0
178 for h, m, _ in im_list:
179 res.paste(m, box=(0, h_now))
180 h_now += h
181 res.save(save_path)
182 # else:
183 # img_dir_path = os.path.join(img_dir, d)
184 # os.makedirs(img_dir_path, exist_ok=True)
...@@ -5,6 +5,7 @@ import datetime ...@@ -5,6 +5,7 @@ import datetime
5 from django.utils import timezone 5 from django.utils import timezone
6 from django.db.utils import IntegrityError 6 from django.db.utils import IntegrityError
7 from django.db.models import Q 7 from django.db.models import Q
8 from rest_framework.permissions import IsAuthenticated
8 from webargs import fields, validate 9 from webargs import fields, validate
9 from webargs.djangoparser import use_args, parser 10 from webargs.djangoparser import use_args, parser
10 from settings import conf 11 from settings import conf
...@@ -15,6 +16,7 @@ from common.redis_cache import redis_handler as rh ...@@ -15,6 +16,7 @@ from common.redis_cache import redis_handler as rh
15 from .models import UploadDocRecords, DocStatus, PriorityApplication, GCAPRecords 16 from .models import UploadDocRecords, DocStatus, PriorityApplication, GCAPRecords
16 from .mixins import DocHandler 17 from .mixins import DocHandler
17 from . import consts 18 from . import consts
19 from apps.account.authentication import OAuth2AuthenticationWithUser
18 20
19 21
20 # restframework将request.body封装至request.data, webargs从request.data中获取参数 22 # restframework将request.body封装至request.data, webargs从request.data中获取参数
...@@ -86,7 +88,9 @@ priority_doc_args = { ...@@ -86,7 +88,9 @@ priority_doc_args = {
86 88
87 89
88 class UploadDocView(GenericView, DocHandler): 90 class UploadDocView(GenericView, DocHandler):
89 permission_classes = [] 91 permission_classes = [IsAuthenticated]
92 authentication_classes = [OAuth2AuthenticationWithUser]
93 # required_scopes = ['write']
90 94
91 # 上传(接收)文件接口 95 # 上传(接收)文件接口
92 @use_args(doc_upload_args, location='data') 96 @use_args(doc_upload_args, location='data')
...@@ -134,8 +138,8 @@ class UploadDocView(GenericView, DocHandler): ...@@ -134,8 +138,8 @@ class UploadDocView(GenericView, DocHandler):
134 is_priority = PriorityApplication.objects.filter(application_id=application_id, on_off=True).exists() 138 is_priority = PriorityApplication.objects.filter(application_id=application_id, on_off=True).exists()
135 value = ['{0}_{1}'.format(prefix, doc.id)] 139 value = ['{0}_{1}'.format(prefix, doc.id)]
136 redis_res = rh.enqueue(value, is_priority) 140 redis_res = rh.enqueue(value, is_priority)
137 self.running_log.info('[doc upload success] [args={0}] [record_id={1}] [is_hil={2}] [doc_id={3}] ' 141 self.running_log.info('[doc upload success] [args={0}] [record_id={1}] [prefix={2}] [doc_id={3}] '
138 '[is_priority={4}] [enqueue_res={5}]'.format(args, record.id, is_hil, doc.id, 142 '[is_priority={4}] [enqueue_res={5}]'.format(args, record.id, prefix, doc.id,
139 is_priority, redis_res)) 143 is_priority, redis_res))
140 return response.ok() 144 return response.ok()
141 145
...@@ -160,7 +164,8 @@ class UploadDocView(GenericView, DocHandler): ...@@ -160,7 +164,8 @@ class UploadDocView(GenericView, DocHandler):
160 164
161 165
162 class PriorityDocView(GenericView, DocHandler): 166 class PriorityDocView(GenericView, DocHandler):
163 permission_classes = [] 167 permission_classes = [IsAuthenticated]
168 authentication_classes = [OAuth2AuthenticationWithUser]
164 169
165 # 优先级订单接口 170 # 优先级订单接口
166 @use_args(priority_doc_args, location='data') 171 @use_args(priority_doc_args, location='data')
...@@ -195,6 +200,25 @@ class PriorityDocView(GenericView, DocHandler): ...@@ -195,6 +200,25 @@ class PriorityDocView(GenericView, DocHandler):
195 args, task_str_list, enqueue_res)) 200 args, task_str_list, enqueue_res))
196 return response.ok() 201 return response.ok()
197 202
203 post.openapi_doc = '''
204 tags: [doc]
205 summary: GCAP提高申请单对应文件优先级
206 consumes: [application/json]
207 produces: [application/json]
208 parameters:
209 - in: body
210 name: body
211 required: true
212 schema:
213 $ref: "#/definitions/Application"
214
215 responses:
216 200:
217 description: ok
218 schema:
219 $ref: '#/definitions/ApiResponse'
220 '''
221
198 222
199 class DocView(GenericView, DocHandler): 223 class DocView(GenericView, DocHandler):
200 224
......
...@@ -22,4 +22,5 @@ urlpatterns = [ ...@@ -22,4 +22,5 @@ urlpatterns = [
22 path(r'api/create/', include('apps.doc.create_urls')), 22 path(r'api/create/', include('apps.doc.create_urls')),
23 path(r'api/priority/', include('apps.doc.priority_urls')), 23 path(r'api/priority/', include('apps.doc.priority_urls')),
24 path(r'api/doc/', include('apps.doc.internal_urls')), 24 path(r'api/doc/', include('apps.doc.internal_urls')),
25 path('api/oauth/', include('oauth2_provider.urls', namespace='oauth2_provider')),
25 ] 26 ]
......
...@@ -12,10 +12,26 @@ tags: ...@@ -12,10 +12,26 @@ tags:
12 schemes: 12 schemes:
13 - "https" 13 - "https"
14 - "http" 14 - "http"
15 security:
16 - OAuth2: []
15 ''' 17 '''
16 18
17 # scheme: bearer 19 # scheme: oauth
18 security_definitions = ''' 20 security_definitions = '''
21 OAuth2:
22 type: oauth2
23 flow: application
24 description: >
25 This API uses OAuth 2 with the application(clientCredentials) grant flow.
26
27 client_id=sMlciTkppsMzARwHpCVarm5q7DP2Vucj3ny8JFhw
28
29 client_secret=WNoOilDx140ZLcenDKfsnikv7S2LIFs60DciYoqnrZaYLqYsKpcmt7mJIL69o9AEf84uQvRnS3K2UioxfjNyImjR4UOyXbDcF6qYgTLC4KDVByKFdVhKfrn2Lc4q4BNW
30
31 scopes=write
32 tokenUrl: https://staging-bmw-ocr.situdata.com/api/oauth/token/
33 scopes:
34 write: Grants write access
19 ''' 35 '''
20 36
21 responses = ''' 37 responses = '''
...@@ -99,6 +115,46 @@ Doc: ...@@ -99,6 +115,46 @@ Doc:
99 type: string 115 type: string
100 example: '8410480' 116 example: '8410480'
101 117
118 Application:
119 type: object
120 required: [APPLICATION_INFORMATION]
121 properties:
122 APPLICATION_INFORMATION:
123 description: 申请单信息
124 type: object
125 required: [SUBMIT_DATETIME, STATUS, ENTITY, RATING, APPLICATION_ID, APPLICATION_VERSION, INTERMEDIATE_DECISION]
126 properties:
127 SUBMIT_DATETIME:
128 description: 提交时间
129 type: string
130 example: 2020-07-08T18:33:31.000+08:00
131 STATUS:
132 description: 状态
133 type: integer
134 example: 42
135 ENTITY:
136 description: 业务类型
137 type: string
138 example: CO00001
139 enum: [CO00001, CO00002]
140 RATING:
141 description: 排名
142 type: integer
143 example: 4
144 APPLICATION_ID:
145 description: 申请id
146 type: string
147 example: CH-B0011010101
148 APPLICATION_VERSION:
149 description: 申请版本
150 type: integer
151 example: 1
152 INTERMEDIATE_DECISION:
153 description: ''
154 type: string
155 example: MUW
156
157
102 ApiResponse: 158 ApiResponse:
103 description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容 159 description: 响应对象,code字段用于表示响应的状态; data字段用于存放响应内容
104 type: object 160 type: object
......
...@@ -4,6 +4,7 @@ from django.core.exceptions import PermissionDenied ...@@ -4,6 +4,7 @@ from django.core.exceptions import PermissionDenied
4 from django.utils.translation import ugettext_lazy as _ 4 from django.utils.translation import ugettext_lazy as _
5 from django.http import Http404 5 from django.http import Http404
6 from rest_framework import exceptions, status 6 from rest_framework import exceptions, status
7 from rest_framework.exceptions import NotAuthenticated, PermissionDenied
7 from rest_framework.response import Response 8 from rest_framework.response import Response
8 from marshmallow.exceptions import ValidationError 9 from marshmallow.exceptions import ValidationError
9 10
...@@ -29,7 +30,9 @@ def exception_handler(exc, context): ...@@ -29,7 +30,9 @@ def exception_handler(exc, context):
29 if getattr(exc, 'wait', None): 30 if getattr(exc, 'wait', None):
30 headers['Retry-After'] = '%d' % exc.wait 31 headers['Retry-After'] = '%d' % exc.wait
31 32
32 if exc.status_code == 403: 33 if isinstance(exc, NotAuthenticated) or isinstance(exc, PermissionDenied):
34 data = res_content(MetaStatus.NO_PERMISSION.value, MetaStatus.NO_PERMISSION.verbose_name)
35 elif exc.status_code == 403:
33 data = res_content(MetaStatus.NEED_LOGIN.value, MetaStatus.NEED_LOGIN.verbose_name) 36 data = res_content(MetaStatus.NEED_LOGIN.value, MetaStatus.NEED_LOGIN.verbose_name)
34 else: 37 else:
35 data = res_content(MetaStatus.INTERNAL_ERROR.value, exc.detail) 38 data = res_content(MetaStatus.INTERNAL_ERROR.value, exc.detail)
......
...@@ -48,7 +48,7 @@ class Command(BaseCommand): ...@@ -48,7 +48,7 @@ class Command(BaseCommand):
48 view_class = view.view_class 48 view_class = view.view_class
49 url_path, path_parameters = pattern[0][0] 49 url_path, path_parameters = pattern[0][0]
50 url_path = unify_url_path_format(url_path) 50 url_path = unify_url_path_format(url_path)
51 if url_path != '/api/create/v1': 51 if url_path not in ['/api/create/v1', '/api/priority/v1']:
52 continue 52 continue
53 url_path_paramters = getattr(view, 'parameters_doc', None) 53 url_path_paramters = getattr(view, 'parameters_doc', None)
54 if url_path_paramters: 54 if url_path_paramters:
...@@ -82,7 +82,7 @@ class Command(BaseCommand): ...@@ -82,7 +82,7 @@ class Command(BaseCommand):
82 api_doc_dct[url_path][method] = doc 82 api_doc_dct[url_path][method] = doc
83 doc_dct = yaml.load(base_part) 83 doc_dct = yaml.load(base_part)
84 doc_dct['paths'] = api_doc_dct 84 doc_dct['paths'] = api_doc_dct
85 # doc_dct['securityDefinitions'] = yaml.load(security_definitions) 85 doc_dct['securityDefinitions'] = yaml.load(security_definitions)
86 doc_dct['responses'] = yaml.load(responses) 86 doc_dct['responses'] = yaml.load(responses)
87 doc_dct['definitions'] = yaml.load(definitions) 87 doc_dct['definitions'] = yaml.load(definitions)
88 88
......
...@@ -42,6 +42,7 @@ INSTALLED_APPS = [ ...@@ -42,6 +42,7 @@ INSTALLED_APPS = [
42 'django.contrib.messages', 42 'django.contrib.messages',
43 'django.contrib.staticfiles', 43 'django.contrib.staticfiles',
44 # 'corsheaders', 44 # 'corsheaders',
45 'oauth2_provider',
45 'rest_framework', 46 'rest_framework',
46 'common', 47 'common',
47 'apps.account', 48 'apps.account',
...@@ -145,6 +146,7 @@ REST_FRAMEWORK = { ...@@ -145,6 +146,7 @@ REST_FRAMEWORK = {
145 'DEFAULT_AUTHENTICATION_CLASSES': ( 146 'DEFAULT_AUTHENTICATION_CLASSES': (
146 'rest_framework.authentication.BasicAuthentication', 147 'rest_framework.authentication.BasicAuthentication',
147 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 148 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
149 # 'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
148 ), 150 ),
149 'EXCEPTION_HANDLER': 'common.exceptions.exception_handler' 151 'EXCEPTION_HANDLER': 'common.exceptions.exception_handler'
150 } 152 }
...@@ -173,3 +175,8 @@ JWT_AUTH = { ...@@ -173,3 +175,8 @@ JWT_AUTH = {
173 # 跨域设置 175 # 跨域设置
174 # CORS_ORIGIN_ALLOW_ALL = True 176 # CORS_ORIGIN_ALLOW_ALL = True
175 # CORS_ALLOW_CREDENTIALS = True 177 # CORS_ALLOW_CREDENTIALS = True
178
179 OAUTH2_PROVIDER = {
180 # this is the list of available scopes
181 'SCOPES': {'read': 'Read scope', 'write': 'Write scope'}
182 }
......
This diff could not be displayed because it is too large.
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!