This repository has been archived on 2026-03-31. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
jelly/readme.md
2019-06-18 21:11:15 -07:00

69 lines
3.9 KiB
Markdown

# NOTICE
This project is archived, as the actix-web 1.0 API is a bit different. It's kept up, though, for insight on how some general patterns work.
# Jelly
This is a sample repository showcasing a rather straightforward way to handle user sessions, signup, and authentication in an [actix-web](https://actix.rs) project. I extracted it from something I'm working on as I realized that it can be otherwise tricky to figure out at a glance how all of this fits together (actix-web is still fairly fast moving, and the docs can be... rough).
You might be interested in this project if:
- You want a sample Rust/actix-web project to kick off that has (mostly) sane defaults, and built-in user accounts.
- You're unsure about how to structure an actix-web project, and want an opinionated (not even necessarily correct) starter.
- You're not interested in putting a puzzle together for something as basic as user authentication, and just want it to work.
You might also not be interested in this, and that's cool too. It's licensed as a "do whatever you want" type deal, so... clone away and have fun. Some extra notes are below.
## Setup
- Clone the repo
- `mv example.env .env`, and fill in the values in there
- `diesel migration run` to create the user database table
- `cargo run` to... well, run it. Depending on whether you have `diesel_cli` installed you might need that too.
_Protip: You can integrate [zxcvbn](https://github.com/shssoichiro/zxcvbn-rs) with the existing Validator infrastructure. I didn't rip it out of my stuff for some other reasons, but it works really well!_
## Notes
This is probably still a bit rough around the edges, since I ripped it out of an existing project of mine, but the key things I wanted to solve were:
- User signup/login, with mostly secure cookie defaults
- An easy way to check the current active user/session on each request
- Figuring out how the hell to shove Redis in here - sessions are stored in there instead of the built-in `CookieSessionBackend` you'll find that ships with actix-web.
There's some "middleware" here (`src/users/middleware.rs`) that makes it easy to check the authentication status for the request, and load the associated `User` record. The first one, `request.is_authentication()`, simply checks the session to see if we have anything indicating a `User` is set. The second one, `request.user()`, returns a future that'll provide the actual `User` object.
`FutureResponse` and `future_redirect` are some wrappers around `actix-web` response formats to make the ergonomics of all of this more readable. You can take 'em or leave 'em.
``` rust
use users::middleware::UserAuthentication;
use utils::responses::{FutureResponse, future_redirect};
fn view(request: HttpRequest) -> FutureResponse {
// Check the session is valid, without a database hit to load the user
if let Err(e) = request.is_authenticated() {
return future_redirect("http://www.mozilla.com/");
}
// Call over to Postgres and get that there user
request.user().then(|a| match a {
Ok(user) => {
future_redirect("http://www.duckduckgo.com/")
},
Err(_) => {
future_redirect("http://www.google.com/")
}
}).responder()
}
```
If I was the kind to use Rust nightly in a project, I'd be interested in a derive-esque macro to check auth, ala Django's `@login_required` decorator.
Also, as you read the code, you may notice a lot of this is influenced by Django. I think they got the user model stuff right at some point over the years. Thanks to the `djangohashers` package, this even matches the password hashing Django does.
Oh, and randomly, this includes a simple library for sending emails via [Postmark](https://postmarkapp.com/), since I enjoy their service.
## Questions, Comments, Etc?
- Email: [ryan@rymc.io](mailto:ryan@rymc.io)
- Twitter: [@ryanmcgrath](https://twitter.com/ryanmcgrath/)
- Web: [rymc.io](https://rymc.io/)
## License
Do what you want. Read the license, it'll say the same.