登陸接口設計和實現

---恢復內容開始---數據庫

一、用戶功能設計與設計:

  提供用戶註冊處理django

  提供用戶登陸處理json

  提供路由配置瀏覽器

二、用戶登陸接口設計:

  接受用戶經過POST 方法提交的登陸信息,提交的數據是JSON 格式數據。服務器

  

  從user表中 email 找出匹配的一條記錄, 驗證密碼是否正確cookie

  驗證經過說明是合法的用戶登陸,顯示歡迎頁面session

  驗證失敗返回錯誤狀態碼,4XXapp

  整個過程都採用AJAX異步過程,用戶提交JSON 數據,服務端回去數據後處理,返回JSON  框架

  URL: /user/login異步

  METHOD:POST

三、路由配置:

    

四、登陸代碼:   

 1 # 登陸業務
 2 def login(request:HttpRequest):
 3     play = simplejson.loads(request.body)
 4     try:
 5         # 通常推薦先有索引的放前面
 6         email = play['email']
 7         user = User.objects.filter(email=email).get()
 8 
 9         # 輸入密碼 和 數據庫中密碼對比
10         if bcrypt.checkpw(play['password'].encode(), user.password.encode()):
11             # 驗證經過
12             token = gen_token(user.id)
13             res = JsonResponse({
14                 'user':{
15                     "user_id":user.id,
16                     "name":user.name,
17                     "email":user.email
18                 },
19                 'token':token
20             })
21             res.set_cookie('Jwt', token) # set cookie
22             return res
23         else:
24             return HttpResponseBadRequest(status=400)
25     except Exception as e:
26         return JsonResponse("輸入有誤")

 

  一、將用戶信息返回去,瀏覽器可使用,處了密碼

    二、服務器端經過set_cookie 讓客戶端強行修改cookie(客戶端通常都開啓的cookie)

五、接口認證:

  如何獲取瀏覽器提交的token信息?

  一、使用Header中的Authorization  

    經過這個header增長token信息

    經過header發送數據,方法能夠是post , get

  二、自定義header

    JWT來發送token  

    咱們選擇第二種

   認證:

    基本上全部的業務都須要認證用戶的信息

    在這裏比較時間戳,若是過時,就直接拋未認證401,客戶端收到後就該直接跳轉到登陸頁

    若是沒有提交user id,就直接從新登陸,若是用戶查到了,填充user對象。

     request -》 時間戳比較-》 user id 比較 --》向後執行。

    

    測試: 沒有報錯,就證實是沒有修改過的
    

      提供一個函數,調用業務函數以前,看下,以前是否登錄過

 1 #  只要須要認證的地方均可以加這個功能,是否登錄過
 2 def auth(view_func):
 3     def wrapper(request:HttpRequest):
 4         token = request.META.get('HTTP_JWT', None)
 5         print(token,type(token),'== = = = = ') # str
 6         try:# 獲取到 token中的payload,證實是以前登陸過的用戶
 7             play = jwt.decode(token, KEY, algorithms=['HS256'])
 8             print(play, type(play),'=============')
 9             # 可是雖然是以前的,可是得確保,這一時刻,數據庫中還存在這個用戶嗎,是否激活狀態等
10             user = User.objects.get(pk=play["user_id"])
11             print(user,'====  = = = = = = == ')
12             # 若是查到了,接下來的業務處理:
13             if user:
14                 #查到,也就是已經登陸,要利用這些用戶信息,因此要動態註冊到request中
15                 request.user = user # 這樣,下面執行show方法的時候,就能夠利用這個用戶屬性了
16             # 若是沒查到,user就報錯了,因此這塊不必寫
17             # else:
18             #     return HttpResponseBadRequest()
19         except Exception as e:
20             print(e)
21             return HttpResponseBadRequest('n or p 錯誤')
22         ret = view_func(request)
23         # 這個中間還能夠執行去其餘的業務。。。。。
24         return ret
25     return wrapper
26 
27 @auth -----裝飾器實現
28 def show(request:HttpRequest):
29     # 例如:
30     print(request.user,'==')
31     print(type(request.user))
32     return JsonResponse({'1':7})

 

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

---恢復內容結束---

一、用戶功能設計與設計:

  提供用戶註冊處理

  提供用戶登陸處理

  提供路由配置

二、用戶登陸接口設計:

  接受用戶經過POST 方法提交的登陸信息,提交的數據是JSON 格式數據。

  

  從user表中 email 找出匹配的一條記錄, 驗證密碼是否正確

  驗證經過說明是合法的用戶登陸,顯示歡迎頁面

  驗證失敗返回錯誤狀態碼,4XX

  整個過程都採用AJAX異步過程,用戶提交JSON 數據,服務端回去數據後處理,返回JSON  

  URL: /user/login

  METHOD:POST

三、路由配置:

    

四、登陸代碼:   

 1 # 登陸業務
 2 def login(request:HttpRequest):
 3     play = simplejson.loads(request.body)
 4     try:
 5         # 通常推薦先有索引的放前面
 6         email = play['email']
 7         user = User.objects.filter(email=email).get()
 8 
 9         # 輸入密碼 和 數據庫中密碼對比
10         if bcrypt.checkpw(play['password'].encode(), user.password.encode()):
11             # 驗證經過
12             token = gen_token(user.id)
13             res = JsonResponse({
14                 'user':{
15                     "user_id":user.id,
16                     "name":user.name,
17                     "email":user.email
18                 },
19                 'token':token
20             })
21             res.set_cookie('Jwt', token) # set cookie
22             return res
23         else:
24             return HttpResponseBadRequest(status=400)
25     except Exception as e:
26         return JsonResponse("輸入有誤")

 

  一、將用戶信息返回去,瀏覽器可使用,處了密碼

    二、服務器端經過set_cookie 讓客戶端強行修改cookie(客戶端通常都開啓的cookie)

五、接口認證:

  如何獲取瀏覽器提交的token信息?

  一、使用Header中的Authorization  

    經過這個header增長token信息

    經過header發送數據,方法能夠是post , get

  二、自定義header

    JWT來發送token  

    咱們選擇第二種

   認證:

    基本上全部的業務都須要認證用戶的信息

    在這裏比較時間戳,若是過時,就直接拋未認證401,客戶端收到後就該直接跳轉到登陸頁

    若是沒有提交user id,就直接從新登陸,若是用戶查到了,填充user對象。

     request -》 時間戳比較-》 user id 比較 --》向後執行。

    

    測試: 沒有報錯,就證實是沒有修改過的
    

      提供一個函數,調用業務函數以前,看下,以前是否登錄過

 1 #  只要須要認證的地方均可以加這個功能,是否登錄過
 2 def auth(view_func):
 3     def wrapper(request:HttpRequest):
 4         token = request.META.get('HTTP_JWT', None)
 5         print(token,type(token),'== = = = = ') # str
 6         try:# 獲取到 token中的payload,證實是以前登陸過的用戶
 7             play = jwt.decode(token, KEY, algorithms=['HS256'])
 8             print(play, type(play),'=============')
 9             # 可是雖然是以前的,可是得確保,這一時刻,數據庫中還存在這個用戶嗎,是否激活狀態等
10             user = User.objects.get(pk=play["user_id"])
11             print(user,'====  = = = = = = == ')
12             # 若是查到了,接下來的業務處理:
13             if user:
14                 #查到,也就是已經登陸,要利用這些用戶信息,因此要動態註冊到request中
15                 request.user = user # 這樣,下面執行show方法的時候,就能夠利用這個用戶屬性了
16             # 若是沒查到,user就報錯了,因此這塊不必寫
17             # else:
18             #     return HttpResponseBadRequest()
19         except Exception as e:
20             print(e)
21             return HttpResponseBadRequest('n or p 錯誤')
22         ret = view_func(request)
23         # 這個中間還能夠執行去其餘的業務。。。。。
24         return ret
25     return wrapper
26 
27 @auth -----裝飾器實現
28 def show(request:HttpRequest):
29     # 例如:
30     print(request.user,'==')
31     print(type(request.user))
32     return JsonResponse({'1':7})

 

    

     Django的認證:

      

       本項目使用了無session的機制,且用戶信息本身建表管理,因此認證須要本身實現

六、中間件技術Midleware      

   官方定義:在Django的request 和response處理過程當中,由框架提供的hook鉤子

   中間件技術,在1.10以後,發生改變,使用新的定義方式

  參看:https://docs.djangoproject.com/en/1.11/topics/http/middleware/#writing-your-own-middleware

   中間件實現方式:有兩種

     

     

    自定義的中間件,也要在這裏註冊:通常寫在最後,先用框架本身的中間件。

     

     本身寫中間件:https://docs.djangoproject.com/en/1.11/topics/http/middleware/#writing-your-own-middleware

       

       右擊中間件名,選擇copyreference,添加到settings.py中。     

     可是,這樣全部的請求和響應都攔截,咱們還得判斷是否是訪問的想要攔截的view函數,因此,考慮其餘的方法。中間件有不少用途,適當的攔截全部請求和響應,例如瀏覽器端的IP 是否被禁用,UserAgent分析,異常響應的統一處理。

     例如本項目的認證,登陸的時候,就不能用中間件,因此不適合註冊一箇中間件來攔截,而是使用裝飾器,須要攔截的就加上此功能。   

  裝飾器:

    在須要認證 的view 函數上增長認證功能,寫一個裝飾器函數,誰須要認證,就在這個view函數上應用這個裝飾器

  

 1 AUTH_EXPIRE = 8*60*60 # 8 小時過時,能夠卸載settings中,經過from django.conf import settings調用
 2 #  只要須要認證的地方均可以加這個功能,是否登錄過
 3 def auth(view_func):
 4     def wrapper(request:HttpRequest):
 5         token = request.META.get('HTTP_JWT', None)
 6         print(token,type(token),'== = = = = ') # str
 7         try:# 獲取到 token中的payload,證實是以前登陸過的用戶
 8             play = jwt.decode(token, KEY, algorithms=['HS256'])
 9             # 可是雖然是以前的,可是得確保,這一時刻,數據庫中還存在這個用戶嗎,是否激活狀態等
10             # 驗證過時時間: 11 current = datetime.datetime.now().timestamp() 12 if (current - play.get('timestamp', 0)) > AUTH_EXPIRE: 13 return HttpResponse("過時了") 14 
15             user = User.objects.get(pk=play["user_id"])
16             # 若是查到了,接下來的業務處理:
17             if user:
18                 #查到,也就是已經登陸,要利用這些用戶信息,因此要動態註冊到request中
19                 request.user = user # 這樣,下面執行show方法的時候,就能夠利用這個用戶屬性了
20             # 若是沒查到,user就報錯了,因此這塊不必寫
21             # else:
22             #     return HttpResponseBadRequest()
23         except Exception as e:
24             print(e)
25             return HttpResponseBadRequest('n or p 錯誤')
26         ret = view_func(request)
27         # 這個中間還能夠執行去其餘的業務。。。。。
28         return ret
29     return wrapper
30 
31 @auth # 很自由的應用在須要認證的view 函數上。 32 def show(request:HttpRequest):
33     # 例如:
34     print(request.user,'==')
35     print(type(request.user))
36     return JsonResponse({'1':7})

 

     Jwt 過時問題:(過時兩種方式:過時的起點時間    和     到期時間)

      pyjwt 支持過時設定,在decode的時候,若是過時,則拋出異常,

      須要在payload中增長  claim exp。exp要求是一個整數int的時間戳。

          

 1 #  只要須要認證的地方均可以加這個功能,是否登錄過
 2 def auth(view_func):
 3     def wrapper(request:HttpRequest):
 4         token = request.META.get('HTTP_JWT', None)
 5         print(token,type(token),'== = = = = ') # str
 6         try:# 獲取到 token中的payload,證實是以前登陸過的用戶
 7             # 認證的同時,驗證過時時間:過時或拋異常(能夠經過時間判斷,塊過時的時候,續期,set cookie從新發一次)
 8             play = jwt.decode(token, KEY, algorithms=['HS256'])
 9             # 可是雖然是以前的,可是得確保,這一時刻,數據庫中還存在這個用戶嗎,是否激活狀態等
10 
11             user = User.objects.get(pk=play["user_id"])
12             # 若是查到了,接下來的業務處理:
13             if user:
14                 #查到,也就是已經登陸,要利用這些用戶信息,因此要動態註冊到request中
15                 request.user = user # 這樣,下面執行show方法的時候,就能夠利用這個用戶屬性了
16             # 若是沒查到,user就報錯了,因此這塊不必寫
17             # else:
18             #     return HttpResponseBadRequest()
19         except Exception as e:
20             print(e)
21             return HttpResponseBadRequest('n or p 錯誤')
22         ret = view_func(request)
23         # 這個中間還能夠執行去其餘的業務。。。。。
24         return ret
25     return wrapper

      測試用的:exp  claim,此代碼,能夠用於續期,經過判斷,快過時,就經過set cookie從新發一個jwt 過去。 

 1 import jwt
 2 import datetime
 3 import threading
 4 
 5 event = threading.Event()
 6 key = 'jerry'
 7 # 在jwt  的payload中增長 exp  claim
 8 data = jwt.encode({'name':'jerry','exp':int(datetime.datetime.now().timestamp() + 3)}, key)
 9 print(jwt.get_unverified_header(data))# 獲取沒有過時的頭
10 try:
11     while not event.wait(1):
12         print(jwt.decode(data, key))
13         print(datetime.datetime.now().timestamp())
14 except jwt.ExpiredSignatureError as e:# 過時就拋異常
15     print(e)
16     
17 print(jwt.get_unverified_header(data))
相關文章
相關標籤/搜索