Day08:08 - User服务(3) - 後端 - JWT token、修改个人资料

Hej,我是Charlie!
在Day07当中,我们完成了基本的登入跟登出,而在今天我们将完成JWT token跟修改个人资料的部分。

================================◉‿◉=================================

首先来介绍JWT是什麽吧。
JWT的全名是Json Web Token,可以使用密码或者金钥进行签章,适合用在授权的部分。
JWT可以用一些演算法来加密,这次我们要用的是SHA256,而JWT基本的结构如下:

  1. header
  2. payload
  3. signature/encryption data

其中header的部分是声明JWT用的是何种算法,而payload指的是JWT中的资料,而signature / encryption data指的是签章的部分。

而这次我们要使用PyJWT,这次的PyJWT用法如下:

以下取自PyJWT documentation
加密:jwt.encode( {"some": "payload"}, "secret", algorithm="HS256")
解密:jwt.decode(encoded_jwt, "secret", algorithms=["HS256"])

首先是key的部分,这里会使用GRC Generator产生:

https://www.grc.com/passwords.htm

这个网站刷新过後就会有新的密码,所以我们可以取得一组高强度的密码,作为JWT的key使用。

首先先新增tools\token.py,并在token.py当中新增def make_token,先指定key跟expire_time:

import jwt
import time

def make_token(data):
	key = "use your own secret key"
	now = time.time()
	expiretime = 60 * 60

接着创立payload,并且使用jwt.encode:

payload = {
	"username": data.username,
	"expire": now + expiretime
}
return jwt.encode(payload,key,algorithm = 'HS256')

所以在login这边,我们就可以返回我们的JWT:

from tools.token import make_token

token = make_token(user)
return R.ok({"message":"Authorize success","token":token})

加完之後,就可以测试login:
https://ithelp.ithome.com.tw/upload/images/20210922/20141666qnzbR5iAs5.png

可以看到返回了token,同样的也加在注册,注册成功後返回token,让使用者可以直接登入:

token = make_token(user)
return R.created({"message":"User created","token":token})

成功制作完token之後,要做检查token的部分。检查token的部分由於是某些方法、大部分请求都要使用到的,所以我们建立一个装饰器,用来装饰大部分的视图:

import jwt
from users.models import User
from tools.R import R

def logincheck(*methods):
	def _logincheck(func):
		def wrapper(request,*args,**kwargs):
			token = request.META.get("HTTP_AUTHORIZATION")
			if request.method not in methods:
				return func(request,*args,**kwargs)
			if not token:
				return R.badRequest("no token")
			try:
				key = 'replace with your own key'
				res = jwt.decode(token, key, algorithms=['HS256'])
			except jwt.ExpiredSignatureError:
				return R.badRequest("login again")
			except Exception as e:
				return R.internalServerError("Internal Server Error")
			username = res['username']
			user = User.objects.filter(name = username)
			if not user:
				return R.badRequest("User does not exist")
			request.user = user
			return func(request,*args,**kwargs)
		return wrapper
	return _logincheck

如此一来,我们就可以将logincheck装饰在users上:

from tools.login_check import logincheck

@logincheck('PUT','DELETE')
def users(request):

接着是个人资料修改的部分,这里是PUT方法,如果是PUT的话就判别用户存不存在,存在就进行修改操作:

elif request.method == "PUT":
	res = request.body
	user = UserModel()
	user.fromJson(res)
	fuser = User.objects.filter(name = user.username)
	if not fuser:
		return R.badRequest("User does not exist")
	fuser.update(
		name = user.username,
		phone = user.phone,
		address = user.address
	)
	return R.ok("Update success")

如果我们用POSTMAN测试的话,直接发送会显示no token:
https://ithelp.ithome.com.tw/upload/images/20210922/20141666mut5HwlDbl.png

这时我们必须带AUTHORIZATION头,在POSTMAN的header地方编辑,再发送即可更新成功:
https://ithelp.ithome.com.tw/upload/images/20210922/20141666bwpThagDKL.png
https://ithelp.ithome.com.tw/upload/images/20210922/20141666VIdU63yezI.png

================================◉‿◉=================================

Day08结束了!在今天我们完成了JWT token跟修改个人资料的後端的部分,明天我们将完成前端的部分,See ya next day!


<<:  Day09 | Dart 非同步 - Future

>>:  DAY20-JAVA的介面

[Day02] Vue i18n - 导入 & 基础用法

i18n 全写为 internationalization,俗称的多国语系也常被称之为本地化 (L...

Components 与 Props(Day4)

当我们会写基本的 Hello World 之後,就可以开始考虑扩展跟重组我们要撰写的程序码了。我们会...

鬼故事 - 不修拉,这辈子都不可能修的

鬼故事 - 不修拉,这辈子都不可能修的 Credit: 天兵公园 灵感来源:UCCU Hacker ...

Day6中秋节最後还是要吃肉肉阿-欧式地中海风马铃薯柠檬炖鸡

中秋假期最後一天,吃了美式、韩式及日式烧肉,吃了这麽多天大鱼大肉可能有点腻,最後一天想来点清爽的肉肉...

30天打造品牌特色电商网站 Day.18 文字的样子

之前曾在 Day8 有跟大家提过字体常用的样式,今天来带大家深入探讨各式文字怎麽设计,才会带给使用者...