Rust: поток паникует при запуске внутри iframe, но не на обычной вкладке браузера

Я играю с созданием приложения на Zendesk с использованием Rust. Ниже показана функция ржавчины на стороне сервера, которая вызывается в маршруте

pub fn oktaredirectprocessor(mut cookies: Cookies, code: String, state: String) -> bool {
    let cookie_state_string = cookies.get_private("state").unwrap().value().to_string();
    println!("cookie retrieved in oktaredirectprocessor is {}", cookie_state_string);
    if state != cookie_state_string {
        debug!("State did not match");
        false
    }else if code == ""{
        debug!("Code is empty");
        false
    }else{
        let oktarequest: Oktarequest = Oktarequest::new();
        let http = reqwest::Client::new();
        let config = oidc::discovery::discover(&http, oktarequest.issuer).expect("error in config-discovery-oidc");
        let jwks = oidc::discovery::jwks(&http, config.jwks_uri.clone()).expect("error in jwks-discovery-oidc");
        let provider = oidc::discovery::Discovered(config);
        let client = oidc::Client::new(oktarequest.id, oktarequest.secret, oktarequest.redirect, provider, jwks);
        let mut token = client.request_token(&http, code.as_str()).expect("error in request token-oidc");
        client.decode_token(&mut token.id_token).expect("error in decode token oidc");
        client.validate_token(&token.id_token, Some(cookies.get_private("nonce").unwrap().value()), None).expect("error in validate token oidc");               cookies.add_private(Cookie::new("access_token", token.access_token().to_string()));
        true
    }

}

Это работает, когда я запускаю localhost прямо с вкладки браузера. Однако поток паникует, если я запускаю приложение из Zendesk. Ниже приведена обратная связь. Я начинающий кодер и не совсем понимаю.

thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:214:60
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/panicking.rs:50:5
   3: core::option::Option<T>::unwrap
             at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/option.rs:386:21
   4: app_remote::oktaredirecthandler
             at ./src/main.rs:214:28
   5: app_remote::rocket_route_fn_oktaredirecthandler
             at ./src/main.rs:213:4
   6: core::ops::function::Fn::call
             at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/ops/function.rs:70:5
   7: <F as rocket::handler::Handler>::handle
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/handler.rs:177:9
   8: rocket::rocket::Rocket::route
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:296:27
   9: rocket::rocket::Rocket::route_and_process
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:242:34
  10: rocket::rocket::Rocket::dispatch
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:217:28
  11: <rocket::rocket::Rocket as hyper::server::Handler>::handle
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:82:24
  12: hyper::server::Worker<H>::keep_alive_loop
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/mod.rs:340:13
  13: hyper::server::Worker<H>::handle_connection
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/mod.rs:282:15
  14: hyper::server::handle::{{closure}}
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/mod.rs:242:34
  15: hyper::server::listener::spawn_with::{{closure}}
             at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/listener.rs:50:31

Как ни странно, проблематичный "cookies.get_private("state").unwrap()" работает в другой функции даже при запуске внутри Zendesk. Ниже приведена функция, где она работает

fn oktalogin(mut cookies: Cookies) -> Redirect {
    let oktarequest: Oktarequest = Oktarequest::new();
    cookies.add_private(Cookie::new("state", oktarequest.state.clone()));
    cookies.add_private(Cookie::new("nonce", oktarequest.nonce.clone()));
    println!("stored state cookie from random gen is: {}", cookies.get_private("state").unwrap().value().to_string());
    let http = reqwest::Client::new();
    let config = oidc::discovery::discover(&http, oktarequest.issuer).expect("error in config-discovery-oidc");
    let jwks = oidc::discovery::jwks(&http, config.jwks_uri.clone()).expect("error in jwks-discovery-oidc");
    let provider = oidc::discovery::Discovered(config);
    let client = oidc::Client::new(oktarequest.id, oktarequest.secret, oktarequest.redirect, provider, jwks);
    let options = Options{
        scope: Some("openid profile email".to_string()),
        state: Some(oktarequest.state.clone()),
        nonce: Some(oktarequest.nonce.clone()),
        ..Default::default()
        };
    let auth_url = client.auth_url(&options);
    Redirect::to(auth_url.into_string())
}

Мой груз.томл

[dependencies]
rocket = { version = "0.4.5", features = ["private-cookies"] }
rocket_codegen = "0.4.5"
serde = "1.0.116"
serde_derive = "1.0.116"
diesel = { version = "1.4.5", features = ["postgres"] }
dotenv = "0.15.0"
serde_urlencoded = "0.7.0"
oidc = "0.3.0"
ring = "=0.16.15"
log = "0.4.8"
rand = "0.7.3"
reqwest = "=0.9.24"
inth-oauth2 = "0.16.0"
url = "=1.7.2"
serde_json = "1.0"
console_log = { version = "0.2", features = ["color"] }

[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["tera_templates", "json"]

Я не удивлен get_private в вашем втором примере, учитывая, что вы делаете add_private прямо заранее. Использование .unwrap() — это грубый инструмент для предположения, что значение существует. Для проверки файлов cookie вам, вероятно, следует избегать их использования и вместо этого решить, что oktaredirectprocessor следует делать, если ожидаемых файлов cookie нет. Тогда ваш вопрос звучит так: «Почему файлы cookie передаются с использованием локального хоста, а не с использованием zendesk»

kmdreko 14.12.2020 09:23

@kmdreko спасибо, ты прав. Обработка None, брошенного get_private, снимает панику. Есть идеи, что может заставить Zendesk не передавать файлы cookie?

nalin 14.12.2020 10:30

Это зависит от вашего тестирования. Я не знаком с Zendesk, но предполагаю, что он размещен в домене, отличном от локального. Файлы cookie зависят от домена, и iframe может иметь отдельный домен. Домен, размещенный на Zendesk, очевидно, не может видеть файлы cookie, используемые localhost. Однако, если oktalogin (установить файлы cookie) и oktaredirectprocessor (получить файлы cookie) определенно происходят в одном и том же домене, то я не знаю.

kmdreko 14.12.2020 10:40
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
3
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Почему это сработало на локальном хосте, так это то, что cookie остался. Для корректной работы необходимо добавить код, когда cookie не существует, без unwrap().

let cookie_state_string = match cookies.get_private("state") {
    Ok(v) => v.value().to_string(),
    Err(_) => return false,
};

Спасибо, Акихито. Такая обработка позволила избежать паники потоков. Однако файл cookie по-прежнему не сохраняется при запуске из Zendesk. Есть предположения?

nalin 14.12.2020 10:32

Сначала следует вызвать oktalogin, и cookie будет сохранен. Затем войдите в oktaredirectprocessor и получите правильный ответ. Но имя ключа «состояние» слишком популярно, чтобы его можно было перекрыть файлом cookie Zendesk, поэтому он может работать, если изменить имя ключа.

Akihito KIRISAKI 14.12.2020 10:43

Другие вопросы по теме