4个版本
使用旧的Rust 2015
0.2.3 | 2018年7月20日 |
---|---|
0.2.2 | 2018年1月16日 |
0.2.1 | 2017年12月20日 |
0.2.0 | 2017年11月19日 |
2245 在 Web编程
每月23次下载
44KB
316 行
% Rocket-auth-login - Rust Rocket框架的认证和登录库
需要Nightly Rust
使用nightly-2017-11-22-x86_64-pc-windows-msvc测试,在Windows上使用rustup安装并将其设置为默认值:
rustup toolchain install nightly-2017-11-22-x86_64-pc-windows-msvc
rustup default nightly-2017-11-22-x86_64-pc-windows-msvc
或在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
在cargo.toml中添加
rocket-auth-login = "0.5.*"
导入和使用语句
extern crate rocket_auth_login as auth;
use auth::authorization;
描述
Rocket-auth-login是一个用Rust编写的认证和登录处理库。
库
此包提供了特质,您将在程序中定义的两个不同自定义类型上实现这些特质。这些特质包含处理登录表单数据和存储和检索cookie的有用方法。您将定义的两个自定义结构将执行以下操作
-
存储登录表单的内容
- 用于验证用户凭据
-
存储cookie的内容
- 当认证成功时,此结构将被序列化为一个存储在私有cookie中的String
- 可以通过请求保护器检索cookie数据结构,用于指定的用户类型
版本说明
版本2.0将任何传递给重定向方法的cookie的所有权传递出去,这并不方便。版本2.1使用对cookie的可变引用,允许在调用重定向方法后修改它们(重定向结构可以存储在变量中,并在需要时返回)。
数据结构
在您的应用程序中定义两个自定义数据结构,它们将
登录表单数据结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdministratorForm {
pub username: String,
pub password: String,
}
cookie数据结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdministratorCookie {
pub userid: u32,
pub username: String,
pub display: Option<String>,
}
特质实现
特质CookieId
由两个数据结构实现。仅由登录数据结构实现的特质是AuthorizeForm
,而由cookie数据结构实现的特质是AuthorizeCookie
。更详细的示例,请查看任何示例中的administrator.rs
文件。
CookieId
每个 数据结构都必须实现 CookieId
特性。对于 cookie_id()
的实现,两个数据结构应该是相同的,因为这两个数据结构将具有相同的cookie标识符(登录表单数据结构将使用指定的cookie标识符创建cookie,而cookie数据结构将读取与指定标识符关联的cookie)。这是一个只有单个方法的简单特性。对于 cookide_id()
方法的实现如下:
// Both structures will use the same code for the `CookieId`
impl CookieId for {StructNameHere} {
fn cookie_id<'a>() -> &'a str {
"acid"
}
}
AuthorizeCookie
AuthorizeCookie
特性定义了cookie数据结构的几个方法。在cookie数据结构上,你必须实现两个函数,还有一个名为 delete_cookie()
的函数,它有一个默认实现,用于删除具有指定名称的私有cookie,该名称由 CookieId::cookie_id()
指定。在cookie数据结构上你必须实现的函数有
store_cookie(&self) ->String
- 将cookie数据结构序列化为字符串以存储在私有cookie中
retrieve_cookie(String) -> Self
- 从cookie包含的字符串反序列化cookie数据结构
AuthorizeForm
AuthorizeForm
特性定义了在登录表单数据结构上实现的一些方法,其中只有两个必须在你的代码中实现。其余的是可选的。同时,关联类型 CookieType
应该设置为cookie数据结构类型
impl AuthorizeForm for AdministratorForm {
type CookieType = AdministratorCookie;
必需
-
fn authenticate(&self) -> Result<Self::CookieType, AuthFail>
- 通过
&self
参数接受一个登录表单数据结构 - 返回
Ok( CookieType )
,其中CookieType
将被cookie数据结构替换- Err( AuthFail::new(attempted_username.to_string(), reason_auth_failed.to_string()) )
- 通过
-
fn new_form(&str, &str, Option<HashMap<String, String>>) -> Self
- 从提交的表单数据创建登录表单数据结构的新实例。此方法由
FromForm
实现在LoginCont
结构上调用(该容器用于存储登录表单数据结构,请参阅下面的路由示例)。参数包括- 用户名 - 来自名为
username
的输入字段 - 密码 - 来自名为
password
的输入字段 - 其他内容 - 一个
Option<HashMap<String, String>>
,它包含除username
和password
之外的所有表单字段。当用户名和密码字段具有不同的名称时(此时authenticate()
可以在额外的哈希映射中查看字段而不是常规的用户名和密码字段)或者当登录表单需要其他字段时,会使用此内容。
- 用户名 - 来自名为
- 从提交的表单数据创建登录表单数据结构的新实例。此方法由
可选(可以重写)
fn flash_redirect(&self, ok_redir: &str, err_redir: &str, cookies: &mutCookies) -> Result<Redirect, Flash<Redirect>>
- 调用
authenticate()
方法,如果成功则创建私有cookie以登录用户。在身份验证成功后,将用户重定向到ok_redir
页面。如果身份验证失败,则调用fail_url()构建查询字符串,并将其附加到err_redir
(这允许用户名持续存在并在登录表单中填写)并且设置一个FlashMessage(一个一旦读取就会被删除的cookie),表明表单失败的原因。
- 调用
fn 重定向(&self, ok_redir: &str, err_redir: &str, cookies: &mutCookies) -> Result<重定向,重定向>
- 与
flash_redirect()
相同,除了它不设置Flashmessage,它只重定向到ok_redir页面或err_redir页面(带有fail_url()
返回的查询字符串附加)。
- 与
fn fail_url(用户: &str) ->String
- 创建一个查询字符串,并将其附加到url上,以指示用户尝试用哪个用户名登录。默认实现创建以下字符串:"?user={username}",其中{username}是指定的用户名。
fn clean_username(字符串: &str) ->String
- 清洗用户名。默认情况下,它使用来自
sanitize()
方法的sanitization
模块(sanitization.rs)。
- 清洗用户名。默认情况下,它使用来自
fn clean_password(字符串: &str) ->String
- 清洗密码。默认情况下,它使用来自
sanitize_password()
方法的sanitization
模块(sanitization.rs)。
- 清洗密码。默认情况下,它使用来自
fn clean_extras(string: &str) -> String
清洗任何额外字段。默认情况下,它使用来自sanitize()
方法的sanitization
模块(sanitization.rs)。
多用户类型
添加多个用户类型(例如管理员和普通用户类型)是可能的,并且相当简单。为此,只需为每种类型创建两个数据结构(登录表单数据结构和cookie数据结构)并为每种用户类型定义不同的cookie标识符(管理员类型可能返回类似"aid"
的值,而用户类型可能返回类似"uid"
的值)。
路由
在您的路由中,您将使用cookie数据类型作为请求保护程序(确保查看页面的用户已登录为指定的用户类型)。使用AdministratorCookie
类型的路由看起来像
#[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
登录表单处理
登录处理路由将是一个post
路由
#[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)
}
安全性
该库将以明文形式发送密码。强烈建议您使用TLS。甚至有一个示例展示了如何使用此crate的TLS。更改非常少。如果您绝对需要在发送密码之前对密码进行散列,所有示例都包含一个来自http://www.movable-type.co.uk/scripts/sha256.html的sha256.js文件,可用于此目的。此外,login.js文件在第15行附近的注释代码可以用于在发送之前使用sha256.js文件散列密码。此方法极其不推荐。SHA散列速度快,因此非常容易受到彩虹表攻击。不使用TLS时,仅使用散列密码的安全性几乎与明文相同。请使用TLS。(Let's Encrypt)提供免费证书,因此没有理由不在生产环境中使用https。
版权声明:Rocket-auth-login crate和Rust代码示例采用Apache 2.0许可协议。然而,示例中的布局/设计是我创建的。如果您至少在HTML输出中放入一个HTML注释“设计©2017Andrew Prindle”,则可以使用它。其余的应用程序您可以使用而不必向用户显示任何形式的信用,但必须遵守Apache 2.0许可协议的条款。
依赖关系
~12–21MB
~388K SLoC