@expraptor/security
v1.0.8
Published
Simple library to secure node express application
Downloads
13
Maintainers
Readme
@expraptor-security
@expraptor-security is a node.js package for securing an express application.
Installation
$ npm install @expraptor/security
Usage
Simple Usage (using session authentication with a memory user store)
import express from "express";
import session from "express-session";
import security from "@expraptor/security";
const port = 3000;
const app = express();
app.use(session({secret: "secret"}));
app.use(express.urlencoded());
const sec = security(app);
sec.buildAuth().inMemoryUser()
.addUser("john", "john").withRoles("ADMIN").and()
.addUser("jane", "jane").withAuthorities("CLIENT").and()
.addUser("bob", "secret");
sec.httpSecurity().authorize()
.requestMatcher("/client/(.*)").hasRole("ADMIN").hasAuthority("CLIENT")
.and()
.requestMatcher("/").permitAll()
.anyRequest().authenticated();
app.get("/", (req, res) => {
res.send("Welcome, no authentication needed.");
});
app.get("/resource", (req, res) => {
res.send("Welcome, You're authenticated.");
});
app.get("/client", (req, res) => {
res.send("Welcome, you have access to client.");
});
app.listen(port, () => {
console.log(`server is listening on http://localhost:${port}`);
});
Custom User Authenticator (using session authentication with custom user authenticator)
interface UserAuthentication extends security.auth.Authentication {
password: string;
}
class UserAuthenticator implements security.auth.Authenticator {
private store: Record<string, UserAuthentication> = {
paul: {
id: 1,
login: "paul",
password: "paul",
roles: [],
authorities: []
},
bob: {
id: 2,
login: "bob",
password: "secret",
roles: [],
authorities: []
}
};
authenticate(login: string, password: string): security.auth.Authentication {
/**
* You can use a database call to get user
*/
const user = this.store[login];
if (user && user.password === password) {
return user;
}
return undefined;
}
}
sec.buildAuth().authenticator(new UserAuthenticator());
Stateless using WWW Basic Authentication
import express from "express";
import security from "@expraptor/security";
const app = express();
const sec = security(app);
sec.buildAuth()
.basicAuthentication().realm("Basic Authentication App").and()
.inMemoryUser()
.addUser("john", "john").withRoles("ADMIN").and()
.addUser("jane", "jane").withAuthorities("CLIENT").and()
.addUser("bob", "secret");
Stateless using WWW Digest Authentication
import express from "express";
import security from "@expraptor/security";
const app = express();
const sec = security(app);
sec.buildAuth()
.digestAuthentication().realm("Digest Authentication App").and()
.inMemoryUser().digest()
.addUser("john", "79fa2042db7866f3dbe977ef6be1df34").withRoles("ADMIN").and()
.addUser("jane", "101e4095953a37653f29fe0a92ef3e04").withAuthorities("CLIENT").and()
.addUser("bob", "92ba3d31cfb6c840bd41be8dbf057d89");
;
Stateless using JWT Token
First install jsonwebtoken
$ npm install jsonwebtoken
And
import express from "express";
import security from "@expraptor/security";
const app = express();
const port = 3000;
const sec = security(app);
sec.buildAuth().jwtTokenAuthentication("your-256-bit-secret");
sec.httpSecurity().authorize()
.requestMatcher("/").permitAll()
.anyRequest().authenticated();
app.get("/", (req, res) => {
res.send("WELCOME HOME");
});
app.get("/resource", (req, res) => {
res.send("You're authenticated");
});
app.listen(port, () => {
console.log(`server is listening on http://localhost:${port}`);
});
Now to test this example got to https://jwt.io/ and generate a jwt using your-256-bit-secret and put this token in request Authorization header. You can use curl or postman or any http client to test this example.
Put Roles and Authorities
If you want to use roles and authorities in your Token, you have to define a JwtAuthorization to extract them from the decoded token. Suppose that your decoded token is
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"claims": {
"roles": [
"USER"
],
"authorities": [
"CLIENT"
]
}
}
Then your JwtAuthorization
class JwtAuthorizationImpl implements security.auth.token.jwt.JwtAuthorization {
getAuthorities(decoded: any): string[] {
return decoded.claims.authorities;
}
getRoles(decoded: any): string[] {
return decoded.claims.roles;
}
}
sec.buildAuth().jwtTokenAuthentication("your-256-bit-secret")
.jwtAuthorization(new JwtAuthorizationImpl());
sec.httpSecurity().authorize()
.requestMatcher("/").permitAll()
.requestMatcher("/admin").hasRole("ADMIN").and()
.requestMatcher("/client/**").hasAuthority("CLIENT").and()
.anyRequest().authenticated();
app.get("/", (req, res) => {
res.send("WELCOME HOME");
});
app.get("/resource", (req, res) => {
res.send("You're authenticated");
});
app.get("/admin", (req, res) => {
res.send("You're admin");
});
app.get("/client", (req, res) => {
res.send("You have CLIENT authority");
});
app.listen(port, () => {
console.log(`server is listening on http://localhost:${port}`);
});