Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/canduma/canduma
A Rust Boilerplate server with GraphQL API, Diesel, PostgreSQL, session authentication and JWT
https://github.com/canduma/canduma
actix actix-web boilerplate-rust graphql juniper jwt-token micro-service
Last synced: 3 months ago
JSON representation
A Rust Boilerplate server with GraphQL API, Diesel, PostgreSQL, session authentication and JWT
- Host: GitHub
- URL: https://github.com/canduma/canduma
- Owner: canduma
- License: mit
- Created: 2019-10-11T13:22:36.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-10-19T23:44:06.000Z (over 1 year ago)
- Last Synced: 2024-08-04T08:08:55.220Z (6 months ago)
- Topics: actix, actix-web, boilerplate-rust, graphql, juniper, jwt-token, micro-service
- Language: Rust
- Homepage:
- Size: 1.56 MB
- Stars: 809
- Watchers: 20
- Forks: 63
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
[![Status](https://img.shields.io/badge/build-passing-brightgreen)]()
[![Status](https://img.shields.io/badge/pull--request-open-blue)]()# Canduma rust Graphql
`A Rust authentication server with GraphQL API, Diesel, PostgreSQL session authentication and JWT`
This repository contains a GraphQL server with JWT up and running quickly.
It uses [actix-web](https://actix.rs/), [Juniper](https://graphql-rust.github.io/juniper/current/),
[Diesel](http://diesel.rs/) and [jsonwebtoken](https://docs.rs/jsonwebtoken)Your own pull requests are welcome!
## Benchmarks with insert into PostgreSQL
```shell script
▶ ./bombardier -c 125 -n 10000000 http://localhost:3000/graphql -k -f body --method=POST -H "Content-Type: application/json" -s
Bombarding http://localhost:3000/graphql with 10000000 request(s) using 125 connection(s)10000000 / 10000000 [===========================================================================] 100.00% 28777/s 5m47s
Done!
Statistics Avg Stdev Max
Reqs/sec 28788.66 2183.47 34605.95
Latency 4.32ms 543.07us 110.95ms
HTTP codes:
1xx - 0, 2xx - 10000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 20.75MB/s
```## Collection of major crates used in Canduma
- actix - [link](https://actix.rs/)
- actix-web - [link](https://docs.rs/actix-web/)
- diesel - [link](http://diesel.rs/)
- juniper - [link](https://graphql-rust.github.io/juniper/current/)
- chrono - [link](https://docs.rs/chrono/)
- serde_json - [link](https://docs.serde.rs/serde_json/)
- argon2rs - [link](https://github.com/bryant/argon2rs)
- jsonwebtoken - [link](https://docs.rs/jsonwebtoken)
- anyhow - [link](https://github.com/dtolnay/anyhow)
- thiserror - [link](https://github.com/dtolnay/thiserror)
- shrinkwraprs - [link](https://docs.rs/shrinkwraprs/)## Required
- [Rustup](https://rustup.rs/)
- Stable Toolchain: `rustup default stable`
- Diesel cli with postgres `cargo install diesel_cli --no-default-features --features "postgres"`
- PostgreSQL database server or use our docker-compose.yml (require docker)## Getting Started
```sh
git clone https://github.com/clifinger/canduma.git
cd canduma
docker-compose up
cp .env.example .env
diesel setup --database-url='postgres://postgres:canduma@localhost/canduma'
diesel migration run
cargo run
```## Test the GraphQL API with Insomnia
### Register
![Register with Insomnia](docs/images/new-insomnia-register.png)
### Login
![Login with Insomnia](docs/images/new-insomnia-login.png)
### Get my account
![Login with Insomnia](docs/images/new-insomnia-get-me.png)
### Get JWT Token
![Get JWT by GraphQL with Insomnia](docs/images/new-insomnia-grahql-get-jwt.png)
### Set Bearer JWT Token
![Set JWT Token with Insomnia](docs/images/insomnia-set-bearer.png)
### Get decoded JWT by the server (for tests purpose)
![Get JWT decoded Token by GraphQL with Insomnia](docs/images/new-insomnia-grahql-get-jwt-decoded.png)
### Test authentication with session in GraphQL by getting all users (for tests purpose)
![Get all users by GraphQL with Insomnia](docs/images/new-insomnia-grahql-get-users.png)
### Logout
![Logout with Insomnia](docs/images/new-insomnia-logout.png)
### Raw code for Insomnia
```text
############ GraphQL Queries ############
query usersQuery {
users {
name
userUuid
createdAt
}
}query tokenQuery {
token {
bearer
}
}query decodeTokenQuery {
decode {
iss
iat
exp
sub
}
}```
## Test the GraphQL API with VScode REST Client
[VScode plugin](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)
See / open TEST.http file in vscode.
## Build release
```sh
cargo build --release
cd target/release
./canduma
```## Security
### Important security considerations
We use session cookies for authentication.
**Why not JWT authentication?**
[Stop Using JWT for sessions and why your solution doesn't work](http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/)
The use of JWT remains secure only if you use adequate storage.
This boilerplate is built for use in a micro-services architecture.JWT can be use for representing claims to be transferred between two parties.
The private key should only be on this micro-service.
public key can be used on all other parties to decode the token.This boilerplate provides a complete example, so we included JWT also.
### Generate RSA keys for JWT
In development mode you can keep the one in `/keys` folder.
```shell script
// private key
$ openssl genrsa -out rs256-4096-private.rsa 4096// public key
$ openssl rsa -in rs256-4096-private.rsa -pubout > rs256-4096-public.pem
```### Logging
Logging controlled by middleware::Logger [actix.rs](https://actix.rs/docs/errors/)
To enable debug logging set `RUST_LOG=debug` in `.env`
### Testing
#### Initialization
First run `yarn` or `npm install` to get all required packages
#### npm run test
To run you can use `npm run test` or `yarn test`.
The testing system designed to automatically build `canduma` offline and start in `tests/jest.beforeall.js`
We starting `canduma` in order to capture output from both rust and js code using `testci` target#### npm run testci
```bash
$ npm run testci> canduma@ testci /home/olexiyb/b100pro/canduma
> cross-env RUST_LOG=debug DEBUG=canduma:* NODE_ENV=test jestDetermining test suites to run...
$ killall canduma
canduma: no process found$ cargo build
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
canduma:jest.beforeall.js build = { status: 0, signal: null, output: [ null, null, null ], pid: 2447, stdout: null, stderr: null } +0ms$ target/debug/canduma
[2020-04-02T18:17:19Z INFO actix_server::builder] Starting 24 workers
[2020-04-02T18:17:19Z INFO actix_server::builder] Starting server on 0.0.0.0:4000
Listening on 0.0.0.0:4000
started APIcanduma:user.test.js /user/me body='Unauthorized' text="Unauthorized" +0ms
...
[2020-04-02T18:17:22Z DEBUG canduma::user::handler] user_string={"user_uuid":"f7cfa71e-096e-44d0-ae4f-7d16dd9e4baf","email":"[email protected]","role":"bad_role"}
canduma:user.test.js /graphql body={ data: null, errors: [ { message: 'Unauthorized', locations: [Array], path: [Array], extensions: [Object] } ] } +292ms
PASS tests/user.test.js
...
```In example above you see output from jest tests as well as from rust code `debug!("user_string={}", user_string);`
#### CLion
I also highly recommend to use CLion as a dev tool.
I allows to run all tests or individual with single click and analyze logs![alt text](docs/images/clion-1.png)