Last active
June 6, 2019 18:01
-
-
Save isaacgr/3cae75c69d5fe5a33c45bcb1c3c2ab94 to your computer and use it in GitHub Desktop.
JSON Web Token authorization setup for webserver/webclient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import decode from "jwt-decode" | |
import jwt from "jsonwebtoken" | |
class AuthHandlder { | |
// Get a token from the server | |
login(username, password) { | |
const data = { | |
username, | |
password, | |
} | |
// post request with the login info to the server | |
return this.fetch(`/api/login`, { | |
method: "POST", | |
body: JSON.stringify({ | |
username, | |
password, | |
}), | |
}) | |
.then(res => { | |
// we will set the token in local storage | |
// this is storage persistent until explicitly deleted | |
this.setToken(res.token) | |
return Promise.resolve(res) | |
}) | |
.catch(error => { | |
return Promise.reject(error) | |
}) | |
} | |
// Checks if there is a saved token in localstorage and if it's still valid | |
loggedIn() { | |
// get the token from localstorage | |
const token = this.getToken() | |
return !!token && this.isTokenValid(token) | |
} | |
// verify the token is valid | |
isTokenValid(token) { | |
try { | |
return jwt.verify(token, "secretkey", (error, auth) => { | |
if (error) { | |
return false | |
} else { | |
return true | |
} | |
}) | |
} catch (err) { | |
return false | |
} | |
} | |
// saves the users token to localStorage | |
setToken(idToken) { | |
localStorage.setItem("id_token", idToken) | |
} | |
// gets the users token from localStorage | |
getToken() { | |
return localStorage.getItem("id_token") | |
} | |
// clear the users token and data from localStorage | |
logout() { | |
localStorage.removeItem("id_token") | |
} | |
getProfile() { | |
// decode the token to get the user info, can be useful | |
return decode(this.getToken()) | |
} | |
fetch(url, options) { | |
// performs api calls sending the required authentication headers | |
const headers = { | |
Accept: "application/json", | |
"Content-Type": "application/json", | |
} | |
return fetch(url, { | |
headers, | |
...options, | |
}) | |
.then(this._checkStatus) | |
.then(response => response.json()) | |
} | |
_checkStatus(response) { | |
// raises an error in case response status is not a success | |
if (response.status >= 200 && response.status < 300) { | |
// Success status lies between 200 to 300 | |
return response | |
} else { | |
let message = "" | |
return response.json().then(json => { | |
message = json["message"] | |
var error = new Error(message) | |
error.response = response | |
throw error | |
}) | |
} | |
} | |
} | |
// create an instance of the handler and export it to be used by the rest of our application | |
let Auth = new AuthHandler() | |
export default Auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require("express") | |
const bodyParser = require("body-parser") | |
const jwt = require('jsonwebtoken') | |
const app = express() | |
const port = 3000 | |
// parse application/json requests, we'll be making these to login | |
app.use(bodyParser.json()) | |
app.get("/", (req, res) => res.send("Homepage")) | |
app.post('/api/login', (request, response) =>{ | |
// get the username and password from the request body | |
const {username, password} = request.body | |
// verify it somehow | |
if (username === "isaac" && password==="jwt"){ | |
// user is authorized, send them a token | |
jwt.sign( | |
{username}, | |
"secretkey", | |
(error, token) => { | |
if (error){ | |
// return the error message to the user | |
return response.status(400).json(error['message']) | |
} | |
// all good, return the token to the user | |
return response.json({token}) | |
} | |
) | |
} else { | |
// user is unauthorized, send error | |
return response.status(404).send('not authorized') | |
} | |
}) | |
// verify the token | |
app.get("/api/verify", verifyToken, (request, response) => { | |
// we have a token, make sure its valid | |
jwt.verify(request.token, "secretkey", (error, authData) => { | |
// something invalid, return | |
if (error) { | |
return response.status(403).json({ | |
message: "unauthorized", | |
}) | |
} else { | |
// token is valid, return an object with the authData | |
return response.json({ | |
authorized: true, | |
authData, | |
}) | |
} | |
}) | |
}) | |
// verifyToken middleware to make sure token exists | |
function verifyToken(request, response, next) { | |
// get authorization header from request | |
const bearerHeader = request.headers["authorization"] | |
// if it exists, then get the token | |
if (typeof bearerHeader !== "undefined") { | |
const token = bearerHeader.split(" ")[1] | |
// add the token to the request object | |
request.token = token | |
// move on with the calling function | |
next() | |
} else { | |
// no token, reject | |
return response.status(403).json({ | |
message: "unauthorized", | |
}) | |
} | |
} | |
app.listen(port, () => console.log(`Server listening on port ${port}!`)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment