google_devicecode.rs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //!
  2. //! This example showcases the Google OAuth2 process for requesting access to the Google Calendar features
  3. //! and the user's profile.
  4. //!
  5. //! Before running it, you'll need to generate your own Google OAuth2 credentials.
  6. //!
  7. //! In order to run the example call:
  8. //!
  9. //! ```sh
  10. //! GOOGLE_CLIENT_ID=xxx GOOGLE_CLIENT_SECRET=yyy cargo run --example google
  11. //! ```
  12. //!
  13. //! ...and follow the instructions.
  14. //!
  15. use oauth2::basic::BasicClient;
  16. // Alternatively, this can be oauth2::curl::http_client or a custom.
  17. use oauth2::devicecode::{DeviceAuthorizationResponse, ExtraDeviceAuthorizationFields};
  18. use oauth2::reqwest::http_client;
  19. use oauth2::{AuthType, AuthUrl, ClientId, ClientSecret, DeviceAuthorizationUrl, Scope, TokenUrl};
  20. use serde::{Deserialize, Serialize};
  21. use std::collections::HashMap;
  22. use std::env;
  23. #[derive(Debug, Serialize, Deserialize)]
  24. struct StoringFields(HashMap<String, serde_json::Value>);
  25. impl ExtraDeviceAuthorizationFields for StoringFields {}
  26. type StoringDeviceAuthorizationResponse = DeviceAuthorizationResponse<StoringFields>;
  27. fn main() {
  28. let google_client_id = ClientId::new(
  29. env::var("GOOGLE_CLIENT_ID").expect("Missing the GOOGLE_CLIENT_ID environment variable."),
  30. );
  31. let google_client_secret = ClientSecret::new(
  32. env::var("GOOGLE_CLIENT_SECRET")
  33. .expect("Missing the GOOGLE_CLIENT_SECRET environment variable."),
  34. );
  35. let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string())
  36. .expect("Invalid authorization endpoint URL");
  37. let token_url = TokenUrl::new("https://www.googleapis.com/oauth2/v3/token".to_string())
  38. .expect("Invalid token endpoint URL");
  39. let device_auth_url =
  40. DeviceAuthorizationUrl::new("https://oauth2.googleapis.com/device/code".to_string())
  41. .expect("Invalid device authorization endpoint URL");
  42. // Set up the config for the Google OAuth2 process.
  43. //
  44. // Google's OAuth endpoint expects the client_id to be in the request body,
  45. // so ensure that option is set.
  46. let device_client = BasicClient::new(
  47. google_client_id,
  48. Some(google_client_secret),
  49. auth_url,
  50. Some(token_url),
  51. )
  52. .set_device_authorization_url(device_auth_url)
  53. .set_auth_type(AuthType::RequestBody);
  54. // Request the set of codes from the Device Authorization endpoint.
  55. let details: StoringDeviceAuthorizationResponse = device_client
  56. .exchange_device_code()
  57. .unwrap()
  58. .add_scope(Scope::new("profile".to_string()))
  59. .request(http_client)
  60. .expect("Failed to request codes from device auth endpoint");
  61. // Display the URL and user-code.
  62. println!(
  63. "Open this URL in your browser:\n{}\nand enter the code: {}",
  64. details.verification_uri().to_string(),
  65. details.user_code().secret().to_string()
  66. );
  67. // Now poll for the token
  68. let token = device_client
  69. .exchange_device_access_token(&details)
  70. .request(http_client, std::thread::sleep, None)
  71. .expect("Failed to get token");
  72. println!("Google returned the following token:\n{:?}\n", token);
  73. }