Skip to content

Commit c9e24a3

Browse files
authored
Merge pull request #11 from wenewzhang/master
add Cors support
2 parents bbc4914 + c2780c0 commit c9e24a3

File tree

6 files changed

+96
-28
lines changed

6 files changed

+96
-28
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2018"
88
actix-web = "2.0.0"
99
actix-rt = "1.0.0"
1010
actix-service = "1.0.1"
11+
actix-cors = "0.2.0"
1112
log = "0.4.8"
1213
env_logger = "0.7.1"
1314
diesel_migrations = "1.4.0"

README.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Or using [Docker](https://www.docker.com/)
1717
- Create a database in postgres cli or [pgAdmin](https://www.pgadmin.org/) tool
1818
- Rename `.env.sample` to `.env` and update the database connection string in `DATABASE_URL` key.
1919
- Build with release profile: `cargo build --release`
20-
- Run release binary in command line/terminal.
20+
- Run release binary in command line/terminal.
2121
- Windows: `target/release/actix-web-rest-api-with-jwt.exe`
2222
- Linux/UNIX: `target/release/actix-web-rest-api-with-jwt`
2323
- Enjoy! 😄
@@ -32,14 +32,23 @@ Or using [Docker](https://www.docker.com/)
3232
### Address: **`localhost:8000`**
3333

3434
### `GET /api/ping`: Ping
35-
35+
```bash
36+
curl -X GET -i 'http://127.0.0.1:8000/api/ping'
37+
```
3638
- Response:
3739
- 200 OK
3840
```
3941
pong!
4042
```
4143
4244
### `POST /api/auth/signup`: Signup
45+
```bash
46+
curl -X POST -i 'http://127.0.0.1:8000/api/auth/signup' \
47+
-H "Content-Type: application/json" --data '{"username": "c",
48+
"email": "c",
49+
"password": "c" }'
50+
```
51+
4352
- Request body:
4453
```
4554
{
@@ -65,6 +74,10 @@ Or using [Docker](https://www.docker.com/)
6574
```
6675
6776
### `POST /api/auth/login`: Login
77+
```bash
78+
curl -X POST -H 'Content-Type: application/json' -i 'http://127.0.0.1:8000/api/auth/login' \
79+
--data '{"username_or_email":"c", "password":"c"}'
80+
```
6881
- Request body:
6982
```
7083
{
@@ -90,7 +103,16 @@ Or using [Docker](https://www.docker.com/)
90103
}
91104
```
92105
106+
### `POST /api/auth/login`: Logout
107+
```bash
108+
curl -X POST -H 'Content-Type: application/json' -H 'Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzcyNTc4NzksImV4cCI6MTU3Nzg2MjY3OSwidXNlciI6ImMiLCJsb2dpbl9zZXNzaW9uIjoiYzUxNWE3NTg3NGYzNGVjNGFmNDJmNWE2M2QxMDVjMGYifQ.B9w6FxFdypb5GCRMKXZ9CZWFxQLFjvmPSusMCtcE-Ac' -i 'http://127.0.0.1:8000/api/auth/logout'
109+
```
110+
93111
### `GET /api/address-book`: Get all people information
112+
```
113+
curl -X GET -H 'Content-Type: application/json' -H 'Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzU4NzM4MjksImV4cCI6MTU3NjQ3ODYyOSwidXNlciI6ImMiLCJsb2dpbl9zZXNzaW9uIjoiZjU5N2M3MTIxZTExNDBhMGE0ZjE0YmQ4N2NjM2Q4MWUifQ.6qppDfRgOw45eExJ7MUEwpcu3AUXXe9_ifj_mp7k22k' -i 'http://127.0.0.1:8000/api/address-book'
114+
'
115+
```
94116
- Header:
95117
- Authorization: bearer \<token\>
96118
- Response
@@ -113,6 +135,9 @@ Or using [Docker](https://www.docker.com/)
113135
```
114136
115137
### `GET /api/address-book/{id}`: Get person information by id
138+
```
139+
curl -X GET -H 'Content-Type: application/json' -H 'Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzU4NzM4MjksImV4cCI6MTU3NjQ3ODYyOSwidXNlciI6ImMiLCJsb2dpbl9zZXNzaW9uIjoiZjU5N2M3MTIxZTExNDBhMGE0ZjE0YmQ4N2NjM2Q4MWUifQ.6qppDfRgOw45eExJ7MUEwpcu3AUXXe9_ifj_mp7k22k' -i 'http://127.0.0.1:8000/api/address-book/2'
140+
```
116141
- Param path:
117142
- id: int32
118143
- Header:
@@ -166,6 +191,17 @@ Or using [Docker](https://www.docker.com/)
166191
```
167192
168193
### `POST /api/address-book`: Add person information
194+
```
195+
curl -X POST -H 'Content-Type: application/json' -H 'Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzU4NzM4MjksImV4cCI6MTU3NjQ3ODYyOSwidXNlciI6ImMiLCJsb2dpbl9zZXNzaW9uIjoiZjU5N2M3MTIxZTExNDBhMGE0ZjE0YmQ4N2NjM2Q4MWUifQ.6qppDfRgOw45eExJ7MUEwpcu3AUXXe9_ifj_mp7k22k' -i 'http://127.0.0.1:8000/api/address-book' --data '{
196+
"name": "a",
197+
"gender": true,
198+
"age": 32,
199+
"address": "addr",
200+
"phone": "133",
201+
"email": "e@q.com"
202+
}
203+
'
204+
```
169205
- Header:
170206
- Authorization: bearer \<token\>
171207
- Request body:
@@ -258,3 +294,15 @@ Or using [Docker](https://www.docker.com/)
258294
"data": ""
259295
}
260296
```
297+
### brower OPTIONS curl request example
298+
```
299+
curl -X OPTIONS -i 'http://127.0.0.1:8000/api/login' -H "Origin: http://example.com" -H "Access-Control-Request-Method: POST"
300+
```
301+
- Response
302+
HTTP/1.1 200 OK
303+
content-length: 0
304+
access-control-max-age: 3600
305+
access-control-allow-methods: POST,DELETE,GET,PUT
306+
access-control-allow-origin: *
307+
access-control-allow-headers: authorization,content-type,accept
308+
date: Tue, 07 Jan 2020 15:17:48 GMT

migrations/2019-02-20-054109_create_login_history_table/up.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ CREATE TABLE login_history
44
id SERIAL PRIMARY KEY NOT NULL,
55
user_id BIGINT NOT NULL REFERENCES users(id),
66
login_timestamp TIMESTAMP WITH TIME ZONE NOT NULL
7-
);
7+
);

src/main.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extern crate serde_derive;
1313
#[macro_use]
1414
extern crate serde_json;
1515
extern crate actix_rt;
16+
extern crate actix_cors;
1617
extern crate env_logger;
1718
extern crate serde;
1819
extern crate dotenv;
@@ -34,16 +35,17 @@ mod schema;
3435
mod services;
3536
mod utils;
3637

37-
use actix_web::{HttpServer, App};
38+
use actix_web::{http, HttpServer, App};
3839
use actix_service::Service;
3940
use futures::FutureExt;
4041
use std::{io, env};
42+
use std::default::Default;
43+
use actix_cors::Cors;
4144

4245
#[actix_rt::main]
4346
async fn main() -> io::Result<()> {
4447
dotenv::dotenv().expect("Failed to read .env file");
4548
env::set_var("RUST_LOG", "actix_web=debug");
46-
4749
env_logger::init();
4850

4951
let app_host = env::var("APP_HOST").expect("APP_HOST not found.");
@@ -55,6 +57,14 @@ async fn main() -> io::Result<()> {
5557

5658
HttpServer::new(move || {
5759
App::new()
60+
.wrap(Cors::new() // allowed_origin return access-control-allow-origin: * by default
61+
// .allowed_origin("http://127.0.0.1:8080")
62+
.send_wildcard()
63+
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
64+
.allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
65+
.allowed_header(http::header::CONTENT_TYPE)
66+
.max_age(3600)
67+
.finish())
5868
.data(pool.clone())
5969
.wrap(actix_web::middleware::Logger::default())
6070
.wrap(crate::middleware::authen_middleware::Authentication)

src/middleware/authen_middleware.rs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{config::db::Pool, constants, models::response::ResponseBody, utils::token_utils};
22
use actix_service::{Service, Transform};
33
use actix_web::{
4+
http::{Method},
45
dev::{ServiceRequest, ServiceResponse},
56
Error, HttpResponse,
67
};
@@ -12,6 +13,7 @@ use std::{
1213
pin::Pin,
1314
task::{Context, Poll},
1415
};
16+
use actix_web::http::header::{HeaderName, HeaderValue};
1517

1618
pub struct Authentication;
1719

@@ -55,35 +57,42 @@ where
5557
let mut authenticate_pass: bool = false;
5658

5759
// Bypass some account routes
58-
for ignore_route in constants::IGNORE_ROUTES.iter() {
59-
if req.path().starts_with(ignore_route) {
60-
authenticate_pass = true;
60+
debug!("{:?}",req.head_mut().headers());
61+
let headers = req.headers_mut();
62+
headers.append(HeaderName::from_static("content-length"),HeaderValue::from_static("true"));
63+
if Method::OPTIONS == *req.method() {
64+
authenticate_pass = true;
65+
} else {
66+
for ignore_route in constants::IGNORE_ROUTES.iter() {
67+
debug!("route:{}",ignore_route);
68+
if req.path().starts_with(ignore_route) {
69+
authenticate_pass = true;
70+
}
6171
}
62-
}
63-
64-
if let Some(pool) = req.app_data::<Pool>() {
65-
info!("Connecting to database...");
66-
if let Some(authen_header) = req.headers_mut().get(constants::AUTHORIZATION) {
67-
info!("Parsing authorization header...");
68-
if let Ok(authen_str) = authen_header.to_str() {
69-
if authen_str.starts_with("bearer") || authen_str.starts_with("Bearer") {
70-
info!("Parsing token...");
71-
let token = authen_str[6..authen_str.len()].trim();
72-
if let Ok(token_data) = token_utils::decode_token(token.to_string()) {
73-
info!("Decoding token...");
74-
if token_utils::verify_token(&token_data, &pool).is_ok() {
75-
info!("Valid token");
76-
authenticate_pass = true;
77-
} else {
78-
error!("Invalid token");
72+
if !authenticate_pass {
73+
if let Some(pool) = req.app_data::<Pool>() {
74+
info!("Connecting to database...");
75+
if let Some(authen_header) = req.headers_mut().get(constants::AUTHORIZATION) {
76+
info!("Parsing authorization header...");
77+
if let Ok(authen_str) = authen_header.to_str() {
78+
if authen_str.starts_with("bearer") || authen_str.starts_with("Bearer") {
79+
info!("Parsing token...");
80+
let token = authen_str[6..authen_str.len()].trim();
81+
if let Ok(token_data) = token_utils::decode_token(token.to_string()) {
82+
info!("Decoding token...");
83+
if token_utils::verify_token(&token_data, &pool).is_ok() {
84+
info!("Valid token");
85+
authenticate_pass = true;
86+
} else {
87+
error!("Invalid token");
88+
}
89+
}
7990
}
8091
}
8192
}
8293
}
8394
}
8495
}
85-
86-
error!("{}", constants::MESSAGE_PROCESS_TOKEN_ERROR);
8796
if authenticate_pass {
8897
let fut = self.service.call(req);
8998
Box::pin(async move {

src/schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ allow_tables_to_appear_in_same_query!(
3434
login_history,
3535
people,
3636
users,
37-
);
37+
);

0 commit comments

Comments
 (0)