1. Authentication & Authorization
Authentication
Authentication is the process of verifying the identification of a person or a device. One of the authentication processes is login process. Once you sign up to a website, your information(id, password, name, email, etc) is stored in its database. After then, you don’t need to create an account to provide your information. Rather, you just give your user id and password to verify your identity and the website will automatically know it is you who is accessing.
Authorization
Authorization is a security mechanism used to determine user privileges or access levels. On many community websites, only the one who uploaded the post and admins can delete it. When someone else tries to delete a post, the website should throw an error(but in many cases, they can’t even see the delete button). So for each request, users need to prove that they have permission.
2. JWT
What Is JWT?
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object(link). You can use JWT to authenticate and authorize requests.
JWT consists of three concatenated Base64url-encoded strings - header, payload, and signature - and they are separated by a dots(.). Header contains metadata about the type of token and cryptographic algorithms. Signature is used to verify the token’s trustworthy. And payload contains all the necessary data for authentication & authorization.
Storing JWT
Session or Local Storage
When a user logs in, the server creates JWT and sends it to the client-side. Then the client-side stores it to the Session Storage or Local Storage. Each time the client-side sends request which needs authentication or authorization to the server-side, the JWT is sent on the Authorization Header.
Vulnerable to XSS(Cross Site Scripting) attack
Session and Local Storage are accessible through JavaScript. A malicious third party can inject its JS into your website so that it can make requests to the APIs.
Cookie
The server stores the JWT in Cookie and verifies the user with the JWT stored in Cookie.
Vulnerable to CSRF(Cross Site Request Forgery) attack
Cookies are vulnerable to CSRF because they are sent with each request. Therefore a malicious third party can easily craft unintended requests.
JWT in Django
# my_settings.py
# NEVER EVER COMMIT THIS FILE TO GIT
SECRET = {
'SECRET_KEY': 'abcde1234',
'JWT_ALGORITHM': 'HS256'
}
# settings.py
import my_settings
SECRET_KEY = my_settings.SECRET['SECRET_KEY']
JWT_ALGORITHM = my_settings.SECRET['JWT_ALGORITHM']
# user/views.py
import json
from datetime import datetime, timdelta
from django.conf import settings
from django.http import JsonResponse
from django.views import View
import bcrypt
import jwt
from .models import User
from token_utils import user_token
class UserSignInView(View):
def post(self, request):
try:
data = json.loads(request.body)
username = data['username']
pw_input = data['password']
user = User.objects.filter(username=username).first()
if user is None:
return JsonResponse({"message": "INVALID_USERNAME"}, status=401)
if bcrypt.checkpw(pw_input.encode('utf-8'),
user.password.encode('utf-8')):
key = settings.SECRET_KEY
algorithm = settings.JWT_ALGORITHM
token = jwt.encode(
{
'iss': 'me',
'id': user.id,
'exp': datetime.utcnow() + timedelta(days=14)
}, key, algorithm=algorithm).decode('utf-8')
response = JsonResponse(
{
'message': 'SUCCESS'
}, status=200
)
# when using Local/Session Storage instead of Cookie, just send token in JsonResponse
if data.get('remember_me') is not None:
max_age = 14*24*60*60 # 14 days
expires = datetime.strftime(
datetime.utcnow() + timedelta(seconds=max_age),
"%Y-%m-%d %H:%M:%S"
)
response.set_cookie(
'token',
token,
max_age=max_age,
expires=expires,
httponly=True
)
return response
response.set_cookie(
'token',
token,
max_age=None,
expires=None,
httponly=True
)
return response
return JsonResponse({"message": "WRONG_PASSWORD"}, status=401)
except KeyError as e:
return JsonResponse({'message': f'KEY_ERROR: {e}'}, status=400)
except ValueError as e:
return JsonResponse({'message': f'VALUE_ERROR: {e}'}, status=400)
# token_utils.py
import json
from django.conf import settings
from django.http import JsonResponse
import jwt
from user.models import User
def user_token(func):
def wrapper(self, request, *args, **kwargs):
try:
token = request.COOKIES.get('token')
# token = request.headers.get('token')
key = settings.SECRET_KEY
algorithm = settings.JWT_ALGORITHM
if token is None:
return JsonResponse({"message": "INVALID_TOKEN"}, status=401)
decode = jwt.decode(token, key, algorithm=algorithm)
request.user = User.objects.get(id=decode['id'])
except jwt.ExpiredSignatureError:
return JsonResponse({"message": "EXPIRED_TOKEN"}, status=400)
return func(self, request, *args, **kwargs)
return wrapper
Discussion (0)