Giter Club home page Giter Club logo

jwt-api's Introduction

JWT API

This example API shows how to implement JSON Web Token authentication and authorization with ASP.NET Core 7, built from scratch.

Features

  • User registration;
  • Password hashing;
  • Role-based authorization;
  • Login via access token creation;
  • Refresh tokens, to create new access tokens when access tokens expire;
  • Revoking refresh tokens.

Frameworks and Libraries

The API uses the following libraries and frameworks to deliver the functionalities described above:

How to test

I added Swagger to the API, so we can use it to visualize and test all API routes. You can run the application and navigate to /swagger to see the API documentation:

Swagger

You can also test the API using a tool such as Postman. I describe how to use Postman to test the API below.

First of all, clone this repository and open it in a terminal. Then restore all the dependencies and run the project. Since it is configured to use Entity Framework InMemory provider, the project will run without any problems.

$ git clone https://github.com/evgomes/jwt-api.git
$ cd jwt-api/src
$ dotnet restore
$ dotnet run

Creating users

To create a user, make a POST request to http://localhost:5000/api/users specifying a valid e-mail and password. The result will be a new user with common users permission.

{
	"email": "[email protected]",
	"password": "123456"
}

Creating an user

There are already two pre-defined users configured to test the application, one with common users permission and another with admin permissions.

{
	"email": "[email protected]",
	"password": "12345678"
}
{
	"email": "[email protected]",
	"password": "12345678"
}

Requesting access tokens

To request the access tokens, make a POST request to http://localhost:5000/api/login sending a JSON object with user credentials. The response will be a JSON object with:

  • An access token which can be used to access protected API endpoints;
  • A request token, necessary to get a new access token when an access token expires;
  • A long value that represents the expiration date of the token.

Access tokens expire after 30 seconds, and refresh tokens after 60 seconds (you can change this in the appsetings.json).

Requesting a token

Accessing protected data

There are two API endpoints that you can test:

  • http://localhost:5000/api/protectedforcommonusers: users of all roles can access this endpoint if a valid access token is specified;
  • http://localhost:5000/api/protectedforadministrators: only admin users can access this endpoint.

With a valid access token in hands, make a GET request to one of the endpoints mentioned above with the following header added to your request:

Authorization: Bearer your_valid_access_token_here

If you get a token as a common user (a user that has the Common role) and make a request to the endpoint for all users, you will get a response as follows:

Common user

But if you try to pass this token to the endpoint that requires admin permission, you will get a 403 - forbidden response:

403 Forbidden

If you sign in as an admin and make a GET request to the admin endpoint, you will receive the following content as response:

Admin restricted data

If you pass an invalid token to any of the endpoints (a expired one or a token that was changed by hand, for example), you will get a 401 unauthorized response.

401 Unauthorized

Refreshing tokens

Imagine you have a single page application or a mobile app and you do not want the users to have to log in again every time an access token expires. To deal with this, you can get a new token with a valid refresh token. This way, you can keep users logged in without explicitly asking them to sign in again.

To refresh a token, make a POST request to http://localhost:5000/api/token/refresh passing a valid refresh token and the user's e-mail in the body of the request.

{
	"token": "your_valid_refresh_token",
	"userEmail": "[email protected]"
}

You will receive a new token if the specified refresh token and e-mail are valid:

Refreshing token

If the request token is invalid, you will receive a 400 response:

Invalid refresh token

Revoking refresh tokens

Now imagine that you want the user to sign out, or you want to revoke a refresh token for any reason. You can revoke a refresh token making a POST request to http://localhost:5000/api/token/revoke, passing a valid refresh token into the body of the request.

{
	"token": "valid_refresh_token"
}

You will get a 204 No Content response after calling this endpoint.

Revoking token

Considerations

This example was created with the intent of helping people who have doubts on how to implement authentication and authorization in APIs to consume these features in different client applications. JSON Web Tokens are easy to implement and secure.

If you have doubts about the implementation details or if you find a bug, please, open an issue. If you have ideas on how to improve the API or if you want to add a new functionality or fix a bug, please, send a pull request.

jwt-api's People

Contributors

azufre avatar evgomes avatar hemantkd avatar mahmmoudkinawy avatar rebinm49 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jwt-api's Issues

Old token is still valid even after calling refresh token

Hello Gomez,

This is a fantastic implementation of JWT Auth. I have learnt a lot using this code.

I have noticed though, that the old token is still valid even after calling the refresh token endpoint and getting a new token together with a new refresh token. I am able to access the protected endpoint using the old token (in postman).

Any ideas on how I can reset/replace the old token with the new token?

Bug in TokenHandler.cs class

Hi, cloned your repo and found the build failed due to this method in the TokenHandler.cs class:

    public AccessToken CreateAccessToken(User user)
    {
         ....
    }

The line:

var refreshToken = BuildRefreshToken(user);

Should be var refreshToken = BuildRefreshToken();

Refresh Token Allows User to Specify Any Email Address

This code in AuthenticationService doesn't check that the email address in question is associated with the refresh token, so a common user could supply an admin user's email address when hitting /api/token/refresh and as long as the email exists, they will get an access token with that user's claims.

https://github.com/evgomes/jwt-api/blob/master/src/JWTAPI/JWTAPI/Services/AuthenticationService.cs#L49-L53

I have a version of this repo I'm using here which corrects the issue by associating refresh tokens with their user emailaddresses when they are created and when they are accessed:

https://github.com/ardalis/WebApiBestPractices/blob/main/securing_apis/jwtapi/Services/AuthenticationService.cs#L39-L40

HTH

DatabaseSeed

Hi, Your project is very helpful to understand JWT but i cofused about using Database Seeding. Can you explain why did you use it. I'm using MsSql do i still need to implement dataseeding on my code?

running from vs 2017

Hello,

Thank you for your excellent code.
I can run it from the command line, but not from VS2017 (with IIS express). I always get a 404 error.

Any idea ?

One may run by selecting JWTAPI instead of IIS Express, but how to run with IIS

Typos found in the README text

While going through the README text, I found that there are some typos that can be fixed easily and some minor improvements can be done.

Can not refresh token

Hi, thanks for your sharing!

I have a problem here. I can not refresh token, it always return "Invalid refresh token". I have tried bebugging and i found that _refreshTokens is null after created access token.

public RefreshToken TakeRefreshToken(string token)
        {
            if (string.IsNullOrWhiteSpace(token))
                return null;

            var refreshToken = _refreshTokens.SingleOrDefault(t => t.Token == token); // refreshToken is null after i login/create new access token
            if (refreshToken != null)
                _refreshTokens.Remove(refreshToken);

            return refreshToken;
        }

Can you please show me how to solve this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.