How to Implement Authentication and Authorization using JWTs in Rust

In this tutorial, we’ll explain how to implement authentication and authorization using JWTs in a Rust web application.

JSON Web Tokens (JWTs) are a standard for securely representing attributes or claims between systems. They can be used in a client-server fashion to enable stateless authorization, whereas cookies are inherently stateful.

However, they are more flexible than that and can also be used in myriad other ways. A prominent use case is secure user state propagation in a microservice architecture. In such a setup, the use case of JWTs can be purely limited to the backend side, with a stateful authorization mechanism toward the frontend. Upon logging in, a session token is mapped onto a JWT, which is then used within the microservice cluster to authorize requests (access control), but also to distribute state about the user (information distribution).

The advantage of this is that other services, or clients, don’t need to refetch information, which is stored within the JWT. For example, a user role, the user email, or whatever you need to access regularly can be encoded inside a JWT. And because JWTs are cryptographically signed, the data stored within them is secure and can’t be manipulated easily.

In this tutorial, we’ll explain how to implement authentication and authorization using JWTs in a Rust web application. We won’t go into very much detail on JWTs themselves; there are great resources on that topic already.

The example we’ll build will focus more on the access control part of JWTs, so we’ll only save the user ID and the user’s role inside the token — everything we need to make sure a user is allowed to access a resource.

As is custom for security-related blog posts, here is a short disclaimer: The code shown in this blog post is not production ready and shouldn’t be copy/pasted. The sole aim of this example is to show off some of the concepts, techniques, and libraries you might want to use when building an authentication/authorization system.

With that out of the way, let’s get started!

Setup

To follow along, you’ll need a recent Rust installation (1.39+) and a tool to send HTTP requests, such as cURL.

First, create a new Rust project.

cargo new rust-jwt-example
cd rust-jwt-example

Next, edit the Cargo.toml file and add the dependencies you’ll need.

[dependencies]
jsonwebtoken = "=7.2"
tokio = { version = "0.2", features = ["macros", "rt-threaded", "sync", "time"] }
warp = "0.2"
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
chrono = "0.4"

We’ll build the web application using the lightweight warp library, which uses tokio as its async runtime. We’ll use Serde for JSON handling and Thiserror and Chrono to handle errors and dates, respectively.

To deal with the JSON Web Tokens, we’ll use the aptly named jsonwebtoken crate, which is mature and widely used within the Rust ecosystem.

Web server

We’ll start by creating a simple web server with a couple of endpoints and an in-memory user store. In a real application, we would probably have a database for user storage. But since that’s not important for our example, we’ll simply hardcode them in memory.

type Result<T> = std::result::Result<T, error::Error>;
type WebResult<T> = std::result::Result<T, Rejection>;
type Users = Arc<RwLock<HashMap<String, User>>>;

Here we define two helper types for Result, specifying an internal result type for propagating errors throughout the application and an external result type for sending errors to the caller.

We also define the Users type, which is a shared HashMap. This is our in-memory user store and we can initialize it like this:

mod auth;
mod error;

#[derive(Clone)]
pub struct User {
    pub uid: String,
    pub email: String,
    pub pw: String,
    pub role: String,
}

#[tokio::main]
async fn main() {
    let users = Arc::new(RwLock::new(init_users()));
    ...
}

fn init_users() -> HashMap<String, User> {
    let mut map = HashMap::new();
    map.insert(
        String::from("1"),
        User {
            uid: String::from("1"),
            email: String::from("user@userland.com"),
            pw: String::from("1234"),
            role: String::from("User"),
        },
    );
    map.insert(
        String::from("2"),
        User {
            uid: String::from("2"),
            email: String::from("admin@adminaty.com"),
            pw: String::from("4321"),
            role: String::from("Admin"),
        },
    );
    map
}

We use a HashMap, which enables us to easily search by the user’s ID. The map is wrapped in an RwLock because multiple threads can access the users map at the same time. This is also the reason it’s finally put into an Arc — an atomic, reference counted smart pointer — which enables us to share this map between threads.

Since we’re building an asynchronous web service and we can’t know in advance on which threads our handler futures will run, we need to make everything we pass around thread-safe.

We’ll set the users map with two users: one with role User and one with role Admin. Later on, we’ll create endpoints, which can only be accessed with the Admin role. This way, we can test that our authorization logic works as intended.

Since we’re using warp, we also need to build a filter to pass the users map to endpoints.

fn with_users(users: Users) -> impl Filter<Extract = (Users,), Error = Infallible> + Clone {
    warp::any().map(move || users.clone())
}

With this first bit of setup out of the way, we can define some basic routes and start the web server.

#[tokio::main]
async fn main() {
    let users = Arc::new(RwLock::new(init_users()));

    let login_route = warp::path!("login")
        .and(warp::post())
        .and_then(login_handler);

    let user_route = warp::path!("user")
        .and_then(user_handler);
    let admin_route = warp::path!("admin")
        .and_then(admin_handler);

    let routes = login_route
        .or(user_route)
        .or(admin_route)
        .recover(error::handle_rejection);

    warp::serve(routes).run(([127, 0, 0, 1], 8000)).await;
}

pub async fn login_handler() -> WebResult<impl Reply> {
    Ok("Login")
}

pub async fn user_handler() -> WebResult<impl Reply> {
    Ok("User")
}

pub async fn admin_handler() -> WebResult<impl Reply> {
    Ok("Admin")
}

In the above snippet, we define three handlers:

  • POST /login — log in with e-mail and password
  • GET /user — an endpoint for every user
  • GET /admin — an endpoint only for admins

Don’t worry about .recover(error::handle_rejection) yet; we’ll deal with error handling a bit later on.

Authentication

Let’s build the login functionality so users and admins can authenticate.

The first step is to get the credentials inside the login_handler.

#[derive(Deserialize)]
pub struct LoginRequest {
    pub email: String,
    pub pw: String,
}

#[derive(Serialize)]
pub struct LoginResponse {
    pub token: String,
}

This is the API we define for the login mechanism. A client sends an email and password and receives a JSON Web Token as response, which the client can then use to make authenticated requests by putting this token inside the Authorization: Bearer $token header field.

We define this as a body to the login_handler, like this:

async fn main() {
    ...
    let login_route = warp::path!("login")
        .and(warp::post())
        .and(with_users(users.clone()))
        .and(warp::body::json())
        .and_then(login_handler);
    ...
}

In the login_handler, the signature and implementation change to:

pub async fn login_handler(users: Users, body: LoginRequest) -> WebResult<impl Reply> {
    match users.read() {
        Ok(read_handle) => {
            match read_handle
                .iter()
                .find(|(_uid, user)| user.email == body.email && user.pw == body.pw)
            {
                Some((uid, user)) => {
                    let token = auth::create_jwt(&uid, &Role::from_str(&user.role))
                        .map_err(|e| reject::custom(e))?;
                    Ok(reply::json(&LoginResponse { token }))
                }
                None => Err(reject::custom(WrongCredentialsError)),
            }
        }
        Err(_) => Err(reject()),
    }
}

What’s happening here? First, we access the shared Users map by calling .read(), which gives us a read-lock on the map. This is all we need for now.

Then, we iterate over this read-only version of the users map, trying to find a user with the email and pw as provided in the incoming body.

If we don’t find a user, we return a WrongCredentialsError, telling the user they didn’t use valid credentials. Otherwise, we call auth::create_jwt with the existing user’s user ID and role, which returns a token. This is what we send back to the caller.

Let’s look at the auth module next.

In auth.rs, we first define some useful data types and constants.

const BEARER: &str = "Bearer ";
const JWT_SECRET: &[u8] = b"secret";

#[derive(Clone, PartialEq)]
pub enum Role {
    User,
    Admin,
}

impl Role {
    pub fn from_str(role: &str) -> Role {
        match role {
            "Admin" => Role::Admin,
            _ => Role::User,
        }
    }
}

impl fmt::Display for Role {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Role::User => write!(f, "User"),
            Role::Admin => write!(f, "Admin"),
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
struct Claims {
    sub: String,
    role: String,
    exp: usize,
}

The Role enum is simply a mapping of the Admin and User roles, so we don’t have to muck around with strings, which is way too error-prone for security-critical stuff like this.

We also define helper methods to convert from and to strings from the Role enum, since this role is saved within the JWT.

Another important type is Claims. This is the data we will save inside and expect of our JWTs. The sub depicts the so-called subject, so “who,” in this case. exp is the expiration date of the token. We also put the user role in there as a custom data point.

The two constants are the prefix of the expected Authorization header and the very important JWT_SECRET. This is the key with which we sign our JSON Web Tokens. In a real system, this would be a long, securely stored string that is changed regularly. If this secret were to leak, anyone could decode all JWTs created with this secret. You could also use a different secret for each user, for example, which would enable you to easily invalidate all of a user’s tokens in case of a data breach by simply changing this secret.

Let’s look at the create_jwt function next.

use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};

pub fn create_jwt(uid: &str, role: &Role) -> Result<String> {
    let expiration = Utc::now()
        .checked_add_signed(chrono::Duration::seconds(60))
        .expect("valid timestamp")
        .timestamp();

    let claims = Claims {
        sub: uid.to_owned(),
        role: role.to_string(),
        exp: expiration as usize,
    };
    let header = Header::new(Algorithm::HS512);
    encode(&header, &claims, &EncodingKey::from_secret(JWT_SECRET))
        .map_err(|_| Error::JWTTokenCreationError)
}

First, we calculate an expiration date for this token. In this case, we only set it to 60 seconds in the future. This is nice for testing because we don’t have to wait long for the token to expire.

The expiration set can be defined using different strategies, but since these tokens are security-critical and hold sensible information, they definitely should expire at some point. Some systems rely on a refresh token mechanism, setting short (minutes/hours) expiration times and providing a refresh token to the caller, which can be used to get a new token if the old one is expired.

Next, we create the Claims struct with the user’s ID, the user’s role, and the expiration date. After that comes our first interaction with the jsonwebtoken crate.

If you have dealt with JWTs before, you’ll know they consist of three parts:

  1. Header
  2. Payload
  3. Signature

This is reflected here since we create a new header and encode this header, plus our payload (claims) with the above-mentioned secret. If this fails, we return an error. Otherwise, we return the resulting JWT.

Now users can log in to our service, but we don’t have a mechanism for handling authorization yet. We’ll look at that next.

#rust #jwt #security #programming #developer

What is GEEK

Buddha Community

How to Implement Authentication and Authorization using JWTs in Rust

How To Set Up Two-Factor Authentication in cPanel

What is 2FA
Two-Factor Authentication (or 2FA as it often referred to) is an extra layer of security that is used to provide users an additional level of protection when securing access to an account.
Employing a 2FA mechanism is a vast improvement in security over the Singe-Factor Authentication method of simply employing a username and password. Using this method, accounts that have 2FA enabled, require the user to enter a one-time passcode that is generated by an external application. The 2FA passcode (usually a six-digit number) is required to be input into the passcode field before access is granted. The 2FA input is usually required directly after the username and password are entered by the client.

#tutorials #2fa #access #account security #authentication #authentication method #authentication token #cli #command line #cpanel #feature manager #google authenticator #one time password #otp #otp authentication #passcode #password #passwords #qr code #security #security code #security policy #security practices #single factor authentication #time-based one-time password #totp #two factor authentication #whm

Why Use WordPress? What Can You Do With WordPress?

Can you use WordPress for anything other than blogging? To your surprise, yes. WordPress is more than just a blogging tool, and it has helped thousands of websites and web applications to thrive. The use of WordPress powers around 40% of online projects, and today in our blog, we would visit some amazing uses of WordPress other than blogging.
What Is The Use Of WordPress?

WordPress is the most popular website platform in the world. It is the first choice of businesses that want to set a feature-rich and dynamic Content Management System. So, if you ask what WordPress is used for, the answer is – everything. It is a super-flexible, feature-rich and secure platform that offers everything to build unique websites and applications. Let’s start knowing them:

1. Multiple Websites Under A Single Installation
WordPress Multisite allows you to develop multiple sites from a single WordPress installation. You can download WordPress and start building websites you want to launch under a single server. Literally speaking, you can handle hundreds of sites from one single dashboard, which now needs applause.
It is a highly efficient platform that allows you to easily run several websites under the same login credentials. One of the best things about WordPress is the themes it has to offer. You can simply download them and plugin for various sites and save space on sites without losing their speed.

2. WordPress Social Network
WordPress can be used for high-end projects such as Social Media Network. If you don’t have the money and patience to hire a coder and invest months in building a feature-rich social media site, go for WordPress. It is one of the most amazing uses of WordPress. Its stunning CMS is unbeatable. And you can build sites as good as Facebook or Reddit etc. It can just make the process a lot easier.
To set up a social media network, you would have to download a WordPress Plugin called BuddyPress. It would allow you to connect a community page with ease and would provide all the necessary features of a community or social media. It has direct messaging, activity stream, user groups, extended profiles, and so much more. You just have to download and configure it.
If BuddyPress doesn’t meet all your needs, don’t give up on your dreams. You can try out WP Symposium or PeepSo. There are also several themes you can use to build a social network.

3. Create A Forum For Your Brand’s Community
Communities are very important for your business. They help you stay in constant connection with your users and consumers. And allow you to turn them into a loyal customer base. Meanwhile, there are many good technologies that can be used for building a community page – the good old WordPress is still the best.
It is the best community development technology. If you want to build your online community, you need to consider all the amazing features you get with WordPress. Plugins such as BB Press is an open-source, template-driven PHP/ MySQL forum software. It is very simple and doesn’t hamper the experience of the website.
Other tools such as wpFoRo and Asgaros Forum are equally good for creating a community blog. They are lightweight tools that are easy to manage and integrate with your WordPress site easily. However, there is only one tiny problem; you need to have some technical knowledge to build a WordPress Community blog page.

4. Shortcodes
Since we gave you a problem in the previous section, we would also give you a perfect solution for it. You might not know to code, but you have shortcodes. Shortcodes help you execute functions without having to code. It is an easy way to build an amazing website, add new features, customize plugins easily. They are short lines of code, and rather than memorizing multiple lines; you can have zero technical knowledge and start building a feature-rich website or application.
There are also plugins like Shortcoder, Shortcodes Ultimate, and the Basics available on WordPress that can be used, and you would not even have to remember the shortcodes.

5. Build Online Stores
If you still think about why to use WordPress, use it to build an online store. You can start selling your goods online and start selling. It is an affordable technology that helps you build a feature-rich eCommerce store with WordPress.
WooCommerce is an extension of WordPress and is one of the most used eCommerce solutions. WooCommerce holds a 28% share of the global market and is one of the best ways to set up an online store. It allows you to build user-friendly and professional online stores and has thousands of free and paid extensions. Moreover as an open-source platform, and you don’t have to pay for the license.
Apart from WooCommerce, there are Easy Digital Downloads, iThemes Exchange, Shopify eCommerce plugin, and so much more available.

6. Security Features
WordPress takes security very seriously. It offers tons of external solutions that help you in safeguarding your WordPress site. While there is no way to ensure 100% security, it provides regular updates with security patches and provides several plugins to help with backups, two-factor authorization, and more.
By choosing hosting providers like WP Engine, you can improve the security of the website. It helps in threat detection, manage patching and updates, and internal security audits for the customers, and so much more.

Read More

#use of wordpress #use wordpress for business website #use wordpress for website #what is use of wordpress #why use wordpress #why use wordpress to build a website

Ahebwe  Oscar

Ahebwe Oscar

1624067081

REST Implementation Of Django Authentication System for Python

djoser

REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such as registration, login, logout, password reset and account activation. It works with custom user model.

Instead of reusing Django code (e.g. PasswordResetForm), we reimplemented few things to fit better into Single Page App architecture.

Developed by SUNSCRAPERS with passion & patience.

Requirements

To be able to run djoser you have to meet following requirements:

  • Python (3.6, 3.7, 3.8, 3.9)
  • Django (2.2, 3.1)
  • Django REST Framework 3.11.1

If you need to support other versions, please use djoser<2.

Installation

Simply install using pip:

$ pip install djoser

And continue with the steps described at configuration guide.

#django #authentication #rest implementation of django authentication system for python #rest #django authentication system for python #rest implementation

How to Implement Authentication and Authorization using JWTs in Rust

In this tutorial, we’ll explain how to implement authentication and authorization using JWTs in a Rust web application.

JSON Web Tokens (JWTs) are a standard for securely representing attributes or claims between systems. They can be used in a client-server fashion to enable stateless authorization, whereas cookies are inherently stateful.

However, they are more flexible than that and can also be used in myriad other ways. A prominent use case is secure user state propagation in a microservice architecture. In such a setup, the use case of JWTs can be purely limited to the backend side, with a stateful authorization mechanism toward the frontend. Upon logging in, a session token is mapped onto a JWT, which is then used within the microservice cluster to authorize requests (access control), but also to distribute state about the user (information distribution).

The advantage of this is that other services, or clients, don’t need to refetch information, which is stored within the JWT. For example, a user role, the user email, or whatever you need to access regularly can be encoded inside a JWT. And because JWTs are cryptographically signed, the data stored within them is secure and can’t be manipulated easily.

In this tutorial, we’ll explain how to implement authentication and authorization using JWTs in a Rust web application. We won’t go into very much detail on JWTs themselves; there are great resources on that topic already.

The example we’ll build will focus more on the access control part of JWTs, so we’ll only save the user ID and the user’s role inside the token — everything we need to make sure a user is allowed to access a resource.

As is custom for security-related blog posts, here is a short disclaimer: The code shown in this blog post is not production ready and shouldn’t be copy/pasted. The sole aim of this example is to show off some of the concepts, techniques, and libraries you might want to use when building an authentication/authorization system.

With that out of the way, let’s get started!

Setup

To follow along, you’ll need a recent Rust installation (1.39+) and a tool to send HTTP requests, such as cURL.

First, create a new Rust project.

cargo new rust-jwt-example
cd rust-jwt-example

Next, edit the Cargo.toml file and add the dependencies you’ll need.

[dependencies]
jsonwebtoken = "=7.2"
tokio = { version = "0.2", features = ["macros", "rt-threaded", "sync", "time"] }
warp = "0.2"
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
chrono = "0.4"

We’ll build the web application using the lightweight warp library, which uses tokio as its async runtime. We’ll use Serde for JSON handling and Thiserror and Chrono to handle errors and dates, respectively.

To deal with the JSON Web Tokens, we’ll use the aptly named jsonwebtoken crate, which is mature and widely used within the Rust ecosystem.

Web server

We’ll start by creating a simple web server with a couple of endpoints and an in-memory user store. In a real application, we would probably have a database for user storage. But since that’s not important for our example, we’ll simply hardcode them in memory.

type Result<T> = std::result::Result<T, error::Error>;
type WebResult<T> = std::result::Result<T, Rejection>;
type Users = Arc<RwLock<HashMap<String, User>>>;

Here we define two helper types for Result, specifying an internal result type for propagating errors throughout the application and an external result type for sending errors to the caller.

We also define the Users type, which is a shared HashMap. This is our in-memory user store and we can initialize it like this:

mod auth;
mod error;

#[derive(Clone)]
pub struct User {
    pub uid: String,
    pub email: String,
    pub pw: String,
    pub role: String,
}

#[tokio::main]
async fn main() {
    let users = Arc::new(RwLock::new(init_users()));
    ...
}

fn init_users() -> HashMap<String, User> {
    let mut map = HashMap::new();
    map.insert(
        String::from("1"),
        User {
            uid: String::from("1"),
            email: String::from("user@userland.com"),
            pw: String::from("1234"),
            role: String::from("User"),
        },
    );
    map.insert(
        String::from("2"),
        User {
            uid: String::from("2"),
            email: String::from("admin@adminaty.com"),
            pw: String::from("4321"),
            role: String::from("Admin"),
        },
    );
    map
}

We use a HashMap, which enables us to easily search by the user’s ID. The map is wrapped in an RwLock because multiple threads can access the users map at the same time. This is also the reason it’s finally put into an Arc — an atomic, reference counted smart pointer — which enables us to share this map between threads.

Since we’re building an asynchronous web service and we can’t know in advance on which threads our handler futures will run, we need to make everything we pass around thread-safe.

We’ll set the users map with two users: one with role User and one with role Admin. Later on, we’ll create endpoints, which can only be accessed with the Admin role. This way, we can test that our authorization logic works as intended.

Since we’re using warp, we also need to build a filter to pass the users map to endpoints.

fn with_users(users: Users) -> impl Filter<Extract = (Users,), Error = Infallible> + Clone {
    warp::any().map(move || users.clone())
}

With this first bit of setup out of the way, we can define some basic routes and start the web server.

#[tokio::main]
async fn main() {
    let users = Arc::new(RwLock::new(init_users()));

    let login_route = warp::path!("login")
        .and(warp::post())
        .and_then(login_handler);

    let user_route = warp::path!("user")
        .and_then(user_handler);
    let admin_route = warp::path!("admin")
        .and_then(admin_handler);

    let routes = login_route
        .or(user_route)
        .or(admin_route)
        .recover(error::handle_rejection);

    warp::serve(routes).run(([127, 0, 0, 1], 8000)).await;
}

pub async fn login_handler() -> WebResult<impl Reply> {
    Ok("Login")
}

pub async fn user_handler() -> WebResult<impl Reply> {
    Ok("User")
}

pub async fn admin_handler() -> WebResult<impl Reply> {
    Ok("Admin")
}

In the above snippet, we define three handlers:

  • POST /login — log in with e-mail and password
  • GET /user — an endpoint for every user
  • GET /admin — an endpoint only for admins

Don’t worry about .recover(error::handle_rejection) yet; we’ll deal with error handling a bit later on.

Authentication

Let’s build the login functionality so users and admins can authenticate.

The first step is to get the credentials inside the login_handler.

#[derive(Deserialize)]
pub struct LoginRequest {
    pub email: String,
    pub pw: String,
}

#[derive(Serialize)]
pub struct LoginResponse {
    pub token: String,
}

This is the API we define for the login mechanism. A client sends an email and password and receives a JSON Web Token as response, which the client can then use to make authenticated requests by putting this token inside the Authorization: Bearer $token header field.

We define this as a body to the login_handler, like this:

async fn main() {
    ...
    let login_route = warp::path!("login")
        .and(warp::post())
        .and(with_users(users.clone()))
        .and(warp::body::json())
        .and_then(login_handler);
    ...
}

In the login_handler, the signature and implementation change to:

pub async fn login_handler(users: Users, body: LoginRequest) -> WebResult<impl Reply> {
    match users.read() {
        Ok(read_handle) => {
            match read_handle
                .iter()
                .find(|(_uid, user)| user.email == body.email && user.pw == body.pw)
            {
                Some((uid, user)) => {
                    let token = auth::create_jwt(&uid, &Role::from_str(&user.role))
                        .map_err(|e| reject::custom(e))?;
                    Ok(reply::json(&LoginResponse { token }))
                }
                None => Err(reject::custom(WrongCredentialsError)),
            }
        }
        Err(_) => Err(reject()),
    }
}

What’s happening here? First, we access the shared Users map by calling .read(), which gives us a read-lock on the map. This is all we need for now.

Then, we iterate over this read-only version of the users map, trying to find a user with the email and pw as provided in the incoming body.

If we don’t find a user, we return a WrongCredentialsError, telling the user they didn’t use valid credentials. Otherwise, we call auth::create_jwt with the existing user’s user ID and role, which returns a token. This is what we send back to the caller.

Let’s look at the auth module next.

In auth.rs, we first define some useful data types and constants.

const BEARER: &str = "Bearer ";
const JWT_SECRET: &[u8] = b"secret";

#[derive(Clone, PartialEq)]
pub enum Role {
    User,
    Admin,
}

impl Role {
    pub fn from_str(role: &str) -> Role {
        match role {
            "Admin" => Role::Admin,
            _ => Role::User,
        }
    }
}

impl fmt::Display for Role {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Role::User => write!(f, "User"),
            Role::Admin => write!(f, "Admin"),
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
struct Claims {
    sub: String,
    role: String,
    exp: usize,
}

The Role enum is simply a mapping of the Admin and User roles, so we don’t have to muck around with strings, which is way too error-prone for security-critical stuff like this.

We also define helper methods to convert from and to strings from the Role enum, since this role is saved within the JWT.

Another important type is Claims. This is the data we will save inside and expect of our JWTs. The sub depicts the so-called subject, so “who,” in this case. exp is the expiration date of the token. We also put the user role in there as a custom data point.

The two constants are the prefix of the expected Authorization header and the very important JWT_SECRET. This is the key with which we sign our JSON Web Tokens. In a real system, this would be a long, securely stored string that is changed regularly. If this secret were to leak, anyone could decode all JWTs created with this secret. You could also use a different secret for each user, for example, which would enable you to easily invalidate all of a user’s tokens in case of a data breach by simply changing this secret.

Let’s look at the create_jwt function next.

use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};

pub fn create_jwt(uid: &str, role: &Role) -> Result<String> {
    let expiration = Utc::now()
        .checked_add_signed(chrono::Duration::seconds(60))
        .expect("valid timestamp")
        .timestamp();

    let claims = Claims {
        sub: uid.to_owned(),
        role: role.to_string(),
        exp: expiration as usize,
    };
    let header = Header::new(Algorithm::HS512);
    encode(&header, &claims, &EncodingKey::from_secret(JWT_SECRET))
        .map_err(|_| Error::JWTTokenCreationError)
}

First, we calculate an expiration date for this token. In this case, we only set it to 60 seconds in the future. This is nice for testing because we don’t have to wait long for the token to expire.

The expiration set can be defined using different strategies, but since these tokens are security-critical and hold sensible information, they definitely should expire at some point. Some systems rely on a refresh token mechanism, setting short (minutes/hours) expiration times and providing a refresh token to the caller, which can be used to get a new token if the old one is expired.

Next, we create the Claims struct with the user’s ID, the user’s role, and the expiration date. After that comes our first interaction with the jsonwebtoken crate.

If you have dealt with JWTs before, you’ll know they consist of three parts:

  1. Header
  2. Payload
  3. Signature

This is reflected here since we create a new header and encode this header, plus our payload (claims) with the above-mentioned secret. If this fails, we return an error. Otherwise, we return the resulting JWT.

Now users can log in to our service, but we don’t have a mechanism for handling authorization yet. We’ll look at that next.

#rust #jwt #security #programming #developer

I am Developer

1602036957

Laravel 8 REST API Authentication with Passport Example Tutorial

Laravel 8 rest api authentication with passport tutorial, you will learn step by step how to create rest API with laravel 8 passport authentication. And as well as how to install and cofigure passport auth in laravel 8 app.

Laravel 8 API Authentication with Passport Tutorial

Step 1: Download Laravel 8 App
Step 2: Database Configuration
Step 3: Install Passport Auth
Step 4: Passport Configuration
Step 5: Run Migration
Step 6: Create APIs Route
Step 7: Create Passport Auth Controller
Step 8: Now Test Laravel REST API in Postman

https://www.tutsmake.com/laravel-8-rest-api-authentication-with-passport/

#laravel api authentication with passport #laravel 8 api authentication #laravel 8 api authentication token tutorial #laravel 8 api authentication using passport #laravel 8 api authentication session