I am trying to do a JWT token authorization using flask on the backend and Jquery, but Im having trouble implementing it.
I created a @token_required decorator and put it above the home ('/') route so that the only users with tokens can access it.
def token_required(func):
@wraps(func)
def decorated(*args,**kwargs):
token = request.args.get('token')
if not token:
return jsonify({'Alert!' : 'Token is missing!'})
try:
payload = jwt.decode(token,SECRET_KEY)
except:
return jsonify({'Alert!' : 'Invalid token!'})
return func(*args,**kwargs)
return decorated
@app.route('/')
@token_required
def home():
return "You are logged in"
Also I created a register and login functionality that return the token in json.
@app.route('/registerUser',methods=['GET', 'POST'])
def registerUser():
conn = mysql.connect()
cursor = conn.cursor()
if request.method == 'POST':
data = request.get_json()
username = data['username']
email = data['email']
password = data['password']
confirm_password = data['confirmPassword']
if password == confirm_password:
password = generate_password_hash( data['password'],method="sha256")
if isRegistered(email):
return make_response("Email already exists",409)
else:
query_string = "INSERT INTO users_eg(username,email,password)VALUES(%s,%s,%s);"
cursor.execute(query_string, (username,email,password))
conn.commit()
token = jwt.encode({
'user':data['email'],
'expiration': str(datetime.utcnow() + timedelta(minutes=30))
},
SECRET_KEY)
return make_response(jsonify({'token' : token}),201) #I need to redirect the user to home route here.
else:
return make_response("Check confirm password again",400)
@app.route('/loginUser',methods=['GET', 'POST'])
def loginUser():
if request.method == 'POST':
data = request.get_json()
email = data['email']
password = data['password']
if isRegistered(email):
if checkPassword(password):
token = jwt.encode({
'user':data['email'],
'expiration': str(datetime.utcnow() + timedelta(minutes=30))
},
SECRET_KEY)
return make_response(jsonify({'token' : token}),200) #I need to redirect the user to home route here.
else:
return make_response("Password is incorrect",400)
else:
return make_response("Email doesn't exist",400)
From the token returned from both login and register, what do I do with it to get access to the protected route ? Do I need to fetch it from the frontend and put it in headers when logging in?
If you send token through headers from the frontend, does it automatically get checked if the token is valid or not by the decorator function?
I have alot of questions here. sorry.
I tried this on my frontend. Im guessing its wrong as I didn't really know what to do in the frontend. I used localStorage to keep my token, but I am guessing this won't work unless I use react or something.
Registering
$(document).ready(function () {
$("form").on("submit", function (event) {
const userInfo = {
username: $("#username").val(),
email: $("#email").val(),
password: $("#password").val(),
confirmPassword: $("#confirmPassword").val(),
};
$.ajax({
type: "post",
url: "http://127.0.0.1:5000//registerUser",
dataType: "json",
contentType: "application/json",
data: JSON.stringify(userInfo),
success: function (result) {
localStorage.setItem("token", JSON.parse(result.token));
},
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
}
});
event.preventDefault();
});
});
Login
$(document).ready(function () {
$("form").on("submit", function (event) {
const userInfo = {
email: $("#email").val(),
password: $("#password").val(),
};
$.ajax({
type: "get",
url: "http://127.0.0.1:5000//loginUser",
dataType: "json",
contentType: "application/json",
data: JSON.stringify(userInfo),
success: function (result) {
localStorage.setItem(JSON.parse(result.token));
},
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
});
event.preventDefault();
});
});