1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
//! # Google-Oauth
//!
//! ## Description
//! `Google-Oauth` is a server-side verification library for Google oauth2.
//!
//! `Google-Oauth` can help you to verify `id_token` or `access_token` which is generated from Google.
//!
//! ## Usage (async)
//!
//! ### 1. Setup
//! To import `Google-Oauth` to your project, please add this line into your `Cargo.toml`.
//!
//! ```toml
//! [dependencies]
//! google-oauth = { version = "1" }
//! ```
//!
//! If you decided to use `async` function, please select an `async` runtime. Here are some options for you:
//! 1. [tokio](https://github.com/tokio-rs/tokio)
//! 2. [async-std](https://github.com/async-rs/async-std)
//! 3. [actix-web](https://github.com/actix/actix-web)
//!
//! We use [tokio](https://github.com/tokio-rs/tokio) in our example, and refactor our main function like this:
//! ```rust
//! #[tokio::main]
//! // #[async_std::main] // when you use [async-std]
//! // #[actix_web::main] // when you use [actix-web]
//! async fn main() {}
//! ```
//!
//! ### 2. Do Verification (`id_token`)
//!
//! You can get your `client_id` from Google Admin Console (or somewhere else), and an `id_token` has been provided from
//! your user. They are all `string-like`. Use the following code to do verification:
//! ```rust
//! use google_oauth::AsyncClient;
//!
//! #[tokio::main]
//! async fn main() {
//! let client_id = "your client id";
//! let id_token = "the id_token";
//!
//! let client = AsyncClient::new(client_id);
//! /// or, if you want to set the default timeout for fetching certificates from Google, e.g, 30 seconds, you can:
//! /// ```rust
//! /// let client = AsyncClient::new(client_id).timeout(time::Duration::from_sec(30));
//! /// ```
//!
//! let payload = client.validate_id_token(id_token).await.unwrap(); // In production, remember to handle this error.
//!
//! // When we get the payload, that mean the id_token is valid.
//! // Usually we use `sub` as the identifier for our user...
//! println!("Hello, I am {}", &payload.sub);
//! }
//! ```
//!
//! **Do verification without any client id**
//!
//! When no `client_id` is provided for `AsyncClient`, `cliend_id` will not be used when validating `id_token`.
//! In this case, `AsyncClient` will accept all `client_id`.
//! However, Google issuer (`iss`), expiration (`exp`) and JWT hash **CAN NOT** be skipped.
//!
//! ### 3. Do Verification (`AccessToken`)
//!
//! Sometimes, Google will return an `access_token` instead of `id_token`. `Google-Oauth` still provides API for validate
//! `access_token` from Google.
//!
//! Note: when validating `access_token`, we don't matter the `client_id`. So if you just need to validate `access_token`,
//! you can simply pass an empty `client_id`, just like this:
//!
//! ```rust
//! use google_oauth::AsyncClient;
//!
//! #[tokio::main]
//! async fn main() {
//! let access_token = "the access_token";
//!
//! let client = AsyncClient::new("");
//!
//! let payload = client.validate_access_token(access_token).await.unwrap(); // In production, remember to handle this error.
//!
//! // When we get the payload, that mean the id_token is valid.
//! // Usually we use `sub` as the identifier for our user...
//! println!("Hello, I am {}", &payload.sub);
//! }
//! ```
//!
//! Warning: the result of `access_token` is different from the result of `id_token`, although they have a same field `sub`.
//!
//! > For full example, please view ./example/async_client/
//!
//! ## Algorithm Supported
//! For validating `id_token`, Google may use these two kinds of hash algorithm to generate JWTs:
//!
//! - [x] RS256
//! - [ ] ES256
//!
//! However, I cannot find any approach to get a valid `ES256` token, and as a result, I remained a `unimplemented` branch,
//! and return an `Err` if the JWT is `ES256` hashed.
//!
//! Feel free to create a new issue if you have an example. PR is welcome.
//!
//! ## Usage (blocking)
//! `Google-Oauth` also provides a blocking client. You need to enable `blocking` feature:
//! ```toml
//! [dependencies]
//! google-oauth = { version = "1", features = ["blocking"] }
//! ```
//!
//! You can use `google_oauth::Client` to validate tokens:
//! ```rust
//! use google_oauth::Client;
//!
//! let client_id = "your client id";
//! let id_token = "the id_token";
//!
//! let client = Client::new(client_id);
//!
//! let payload = client.validate_id_token(id_token).unwrap();
//!
//! println!("Hello, I am {}", &payload.sub);
//! ```
//!
//! > For full example, please view ./examples/blocking/
//!
//! ## Error Handling
//!
//! Most APIs return an `Result<T, E>`, where `E` is [`Error`].
//! See [`Error`] for more information.
//!
//! ## WebAssembly (wasm)
//! `Google-Oauth` supports wasm, feature `wasm` is required.
//! ```toml
//! [dependencies]
//! google-oauth = { version = "1", features = ["wasm"] }
//! ```
//!
//! You can build this library with ``wasm-pack build --features wasm``. (`cargo install wasm-pack` to install first.)
//!
//! If you need to import `wasm` into your project, you can use `google_oauth::Client` to run async functions.
//!
//! ## Features
//! + `default`: enable `AsyncClient`.
//! + `blocking`: enable `Client`.
//! + `wasm`: disable `AsyncClient` and `Client`(`blocking`), enable `Client` (`wasm`).
//! + `reqwest-rustls`: use rustls as the TLS backend of the Reqwest client
//!
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
type MyResult<T> = Result;
pub use *;
const GOOGLE_SA_CERTS_URL: &str = "https://www.googleapis.com/oauth2/v3/certs";
const GOOGLE_ISS: = ;
const DEFAULT_TIMEOUT: u64 = 5u64;
const GOOGLE_OAUTH_V3_USER_INFO_API: &str = "https://www.googleapis.com/oauth2/v3/userinfo";
compile_error!;