All Projects → vishusandy → rocket-auth-login

vishusandy / rocket-auth-login

Licence: other
Authentication and login processing for Rust's Rocket web framework. Demonstrates a working example of how to authenticate users and process login as well as how to handle logging out.

Programming Languages

rust
11053 projects
PLpgSQL
1095 projects

Projects that are alternatives of or similar to rocket-auth-login

rocket auth
An implementation for an authentication API for Rocket applications.
Stars: ✭ 65 (+25%)
Mutual labels:  web-development, rocket
Rocket
A web framework for Rust.
Stars: ✭ 15,760 (+30207.69%)
Mutual labels:  web-development, rocket
framework
Cygnite PHP Framework- A Modern Toolkit For Web Developers
Stars: ✭ 43 (-17.31%)
Mutual labels:  web-development
geoservices-js
Deprecated - please consider using @esri/arcgis-rest-js
Stars: ✭ 53 (+1.92%)
Mutual labels:  web-development
docker
A few basic docker containers for web development with PHP 7.3, MySQL 5.7 & NGINX 1.15
Stars: ✭ 18 (-65.38%)
Mutual labels:  web-development
msa-toolkit
The MSA Toolkit provides useful codes for flight simulations and analysis, aerodynamic optimization and sensibility analysis. The codes are implemented by the MisSion Analysis Team.
Stars: ✭ 22 (-57.69%)
Mutual labels:  rocket
flask-course
Curso de Flask (Desarrollo Web en Python; Básico)
Stars: ✭ 23 (-55.77%)
Mutual labels:  web-development
Rocket
FreeCAD Rocketry Workbench
Stars: ✭ 29 (-44.23%)
Mutual labels:  rocket
oriented-imagery
Find developer resources for Oriented Imagery, including a Web AppBuilder widget and oriented imagery catalog (OIC) schema.
Stars: ✭ 21 (-59.62%)
Mutual labels:  web-development
configurable-app-examples-4x-js
Configurable Application Examples using ApplicationBase
Stars: ✭ 22 (-57.69%)
Mutual labels:  web-development
devit
The DEVit Web Conference
Stars: ✭ 25 (-51.92%)
Mutual labels:  web-development
node-js-file-upload
NodeJS File upload with GridFS and Multer
Stars: ✭ 26 (-50%)
Mutual labels:  web-development
Systemizer
A system design tool that allows you to simulate data flow of distributed systems.
Stars: ✭ 1,219 (+2244.23%)
Mutual labels:  web-development
auth-rs
Simple username/password authentication system for Rocket
Stars: ✭ 19 (-63.46%)
Mutual labels:  rocket
image-discovery-app-js
JavaScript Image Discovery Web Application. Use to search, discover, filter, and manipulate imagery.
Stars: ✭ 22 (-57.69%)
Mutual labels:  web-development
recurrent
A library for building functional-reactive (FRP) GUIs in Clojurescript
Stars: ✭ 49 (-5.77%)
Mutual labels:  web-development
handbook
A guide for members of the Suncoast Developers Guild
Stars: ✭ 16 (-69.23%)
Mutual labels:  web-development
rich-uncle-pennybags-bot
A telegram bot for all of your crypto needs. Works over the bitfinex and coinmarketcap APIs
Stars: ✭ 15 (-71.15%)
Mutual labels:  rocket
nardis
A small web framework based on ASGI
Stars: ✭ 14 (-73.08%)
Mutual labels:  web-development
RustyRockets
This repository contains a sample that I used to do an introduction talk about Building Web APIs with Rust and Rocket at the Rust Linz meetup.
Stars: ✭ 25 (-51.92%)
Mutual labels:  rocket

% Rocket-auth-login - Authentication and Login library for Rust's Rocket Framework

Requires Nightly Rust

Tested using nightly-2017-11-22-x86_64-pc-windows-msvc To install using rustup in windows and set as default use:

rustup toolchain install nightly-2017-11-22-x86_64-pc-windows-msvc
rustup default nightly-2017-11-22-x86_64-pc-windows-msvc

Or on linux:

rustup toolchain install nightly-2017-11-22-x86_64-unknown-linux-gnu
rustup default nightly-2017-11-22-x86_64-unknown-linux-gnu

Cargo.toml

In the cargo.toml add:

    rocket-auth-login = "0.5.*"

Import and Use Statements


    extern crate rocket_auth_login as auth;
    use auth::authorization;
    

Description

Rocket-auth-login is a library written in Rust for authentication and login processing.

Library

This crate provides traits that you will implement on two different custom types that you define in your program. These traits contain helpful methods to process login form data as well as store and retrieve cookies. The two custom structures that you will define will do the following:

  • Store the contents of your login form

    • This is used to authenticate users' credentials
  • Store the contents of the cookie

    • When authentication is successful this structure will be serialized into a String that is stored in a private cookie
    • The cookie data structure can be retrieved through a request guard for the specified user type

Version Note

The Version 2.0 passes ownership of any cookies passed into the redirection methods which is not very convenient. Version 2.1 uses a mutable reference to the cookies allowing them to be modified after calling the redirect methods (the redirect structure can be held in a variable and returned when needed).

Data Structures

In your application define two custom data structures that will:

Login Form Data Structure


    #[derive(Debug, Clone, Serialize, Deserialize)]    
    pub struct AdministratorForm {
        pub username: String,
        pub password: String,
    }

Cookie Data Structure


    #[derive(Debug, Clone, Serialize, Deserialize)]
    pub struct AdministratorCookie {
        pub userid: u32,
        pub username: String,
        pub display: Option<String>,
    }

Trait Implementations

The trait CookieId is implemented by both data structures. the AuthorizeForm trait is implemented by only the login data structure while the AuthorizeCookie trait is implemented by the cookie data structure. For a more thorough example look at the administrator.rs file in any of the examples.

CookieId

Each data structure will must implement the CookieId trait. The cookie_id() implementation should be the same for both data structures since the two will have the same cookie identifier (the login form data structure will create the cookie with the specified cookie identifier while the cookie data structure will read the cookie associated with the specified identifier). It is a simple trait with only a single method. The implementation for cookide_id() method looks like:


    // Both structures will use the same code for the `CookieId`
    impl CookieId for {StructNameHere} {
        fn cookie_id<'a>() -> &'a str {
            "acid"
        }
    }

AuthorizeCookie

The AuthorizeCookie trait defines methods for the cookie data structure. There are two functions you must implement on the cookie data structure, as well as a thrid function delete_cookie() which has a default implementation that deletes the private cookie with the name specified by CookieId::cookie_id(). The functions you must implement on the cookie data structure are:

  • store_cookie(&self) -> String
    • Serialized a cookie data structure into a string to be stored in the private cookie
  • retrieve_cookie(String) -> Self
    • Deserializes a cookie data structure from a string that the cookie contained

AuthorizeForm

The AuthorizeForm trait defines several methods which are implemented on the login form data structure, only two of which must be implemented in your code. The rest are optional. Also the associated type CookieType should be set to the cookie data structure type


    impl AuthorizeForm for AdministratorForm {
        type CookieType = AdministratorCookie;

Required:

  • fn authenticate(&self) -> Result<Self::CookieType, AuthFail>

    • Takes a login form data structure via the &self parameter
    • Returns either
      • Ok( CookieType ) where CookieType is replaced by the cookie data structure
      • Err( AuthFail::new(attempted_username.to_string(), reason_auth_failed.to_string()) )
  • fn new_form(&str, &str, Option<HashMap<String, String>>) -> Self

    • Creates a new instance of the login form data structure from the submitted form data. This method is called from the FromForm implementation on the LoginCont structure (which the container used to store the login form data structure, see the Routes example below). The parameters are:
      1. Username - comes from an input field named username
      2. Password - comes from an input field named password
      3. Extras - An Option<HashMap<String, String>> which contains every form field other than username and password. This is used when the username and password fields have different names (then authenticate() can look at the fields in the extras hashmap instead of the regular username and password fields) or when other fields are needed in the login form.

Optional (can be overridden):

  • fn flash_redirect(&self, ok_redir: &str, err_redir: &str, cookies: &mut Cookies) -> Result<Redirect, Flash<Redirect>>
    • Call the authenticate() method and if successful creates the private cookie to log the user in. Redirects the user to the ok_redir page on successful authentication. If authentication fails it calls the fail_url() to build a query string which is appended to err_redir (this allows the username to persist and be filled in inside the login form) and also sets a FlashMessage (a cookie that is deleted once read) indicating why the form failed
  • fn redirect(&self, ok_redir: &str, err_redir: &str, cookies: &mut Cookies) -> Result<Redirect, Redirect>
    • Same as flash_redirect() except it does not set a Flashmessage, it only redirects to either the ok_redir page or err_redir page (with the query string returned by fail_url() appended)
  • fn fail_url(user: &str) -> String
    • Creates a query string that is appended to the url to indicate the username the user attempted to login with. The default implementation creates the following string: "?user={username}" where {username} is the specified username
  • fn clean_username(string: &str) -> String
    • Sanitizes the username. By default it uses the sanitize() method from the sanitization module (sanitization.rs)
  • fn clean_password(string: &str) -> String
    • Sanitizes the password. By default it uses the sanitize_password() method from the sanitization module (sanitization.rs)
  • fn clean_extras(string: &str) -> String Sanitizes the any extra fields. By default it uses the sanitize() method from the sanitization module (sanitization.rs)

Multiple User Types

It is possible and fairly simple to add multiple user types, like an administartor and a regular user type. To accomplish this simply two data structures for each type (a login form data structure and a cookie data structure) and define different cookie identifiers for each user type (the admin type may have cookie_id() return something like "aid" while the user type may return something similar to "uid").

Routes

In your routes you will use the cookie data type as a request guard (ensuring that the user viewing the page is logged in as the specified user type). A route that uses the AdministratorCookie type looks like:


    #[get("/login", rank = 1)]
    fn logged_in(_user: AuthCont<AdministratorCookie>) -> Html<String> {
        let admin: AdministratorCookie = _user.cookie;
        Html( format!("Welcome {}, you are logged in as an administrator.", admin.username) )
    }
    // OR to use the type directly
    fn logged_in(admin: AdministratorCookie

Login Form Processing

The login processing route will be a post route that


    #[allow(unused_mut)]
    #[post("/login", data = "<form>")]
    fn process_login(form: Form<LoginCont<AdministratorForm>>, mut cookies: Cookies) -> Result<Redirect, Flash<Redirect>> {
        let inner = form.into_inner();
        let login = inner.form;
        login.flash_redirect("/login", "/login", cookies)
    }

Security

The library will send passwords in plaintext. It is highly recommended that you use TLS. There is even an example showing how to use tls with this crate. The changes are minimal. If you absolutely need to hash a password before the password is sent the examples all include a sha256.js file from http://www.movable-type.co.uk/scripts/sha256.html which can be used for that very purpose. Also the login.js file contains commented out code around line 15 that can be used to hash the password before sending it using the sha256.js file. This method is extremely discouraged. Sha hashes are fast, and thus very susceptible to rainbow table attacks. Without using TLS the security is almost the same as plaintext when using just a hashed password. Use TLS. Let's Encrypt) offers free certificates so there's no reason not to use https for production purposes.

Copyright Note: The Rocket-auth-login crate and Rust code examples are licensed under the Apache 2.0 license. However the layout/design in the examples was created by me. You can use it however if you put in at least an HTML comment inside the HTML output saying Design © 2017 Andrew Prindle. The rest of the application you may use without any kind of credit displayed to users but must follow the terms of the Apache 2.0 license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].