Error al crear passkey de usuario en el navegador

cuando intento crear una passkey en mi propio sitio, me recuerda

El proceso de registro de la passkey ha caducado, ha sido cancelado o no está permitido

pero puedo crear una passkey en el foro de Discourse Meta en el mismo navegador (Microsoft Edge) y con el mismo plugin (Apple Passkey)

he actualizado mi Discourse a la última versión, pero no funciona como en esta publicación

Oye, parece que mostramos un error de consola cuando este mensaje que compartes aparece en un diálogo.

¿Podrías abrir la consola de tu navegador y compartir con nosotros el error que podrías ver?


parece que no hay nada sobre este error en los registros

Necesitarás ver el registro de la consola de tu navegador, no el sitio /logs.

¿Está esto bien?

forum.beginner.center/:1  Contenido mixto: La página en 'https://forum.beginner.center/' se cargó a través de HTTPS, pero solicitó una fuente insegura 'http://forum.beginner.center/fonts/JetBrainsMono-Regular.woff2?v=0.0.19'. Esta solicitud ha sido bloqueada; el contenido debe servirse a través de HTTPS.
forum.beginner.center/:1  Contenido mixto: La página en 'https://forum.beginner.center/' se cargó a través de HTTPS, pero solicitó una fuente insegura 'http://forum.beginner.center/fonts/JetBrainsMono-Bold.woff2?v=0.0.19'. Esta solicitud ha sido bloqueada; el contenido debe servirse a través de HTTPS.
app.js:270 ℹ️ Discourse v3.5.0.beta9-dev — https://github.com/discourse/discourse/commits/33dfd7dba9 — Ember v5.12.0
[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

[Solo informe] Se denegó la evaluación de una cadena como JavaScript porque 'unsafe-eval' no es una fuente permitida de scripts en la siguiente directiva de Política de Seguridad de Contenido: "script-src 'nonce-4YvvTZffYuqGaENC8DnQ7yeNg' 'strict-dynamic'".

analytics.eu.umami.is/script.js:1   Error al cargar el recurso: net::ERR_CONNECTION_CLOSED
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
La prevención de seguimiento bloqueó el acceso al almacenamiento para <URL>.
deprecated.js:62  Aviso de depreciación: Establecer la propiedad timezone del objeto user está obsoleto. Utilice el objeto user_option en su lugar [obsoleto desde Discourse 2.9.0.beta12] [eliminación en Discourse 3.0.0.beta1] [id de depreciación: discourse.user.userOptions]
a @ deprecated.js:62
security:1 El procesamiento de Autofocus fue bloqueado porque un documento ya tiene un elemento enfocado.
completion_list.html:14   GET chrome-extension://mfbcdcnpokpoajjciilocoachedjkima/heuristicsRedefinitions.js net::ERR_FILE_NOT_FOUND
completion_list.html:13   GET chrome-extension://mfbcdcnpokpoajjciilocoachedjkima/extensionState.js net::ERR_FILE_NOT_FOUND
completion_list.html:12   GET chrome-extension://mfbcdcnpokpoajjciilocoachedjkima/utils.js net::ERR_FILE_NOT_FOUND
ajax.js:188   POST https://forum.beginner.center/u/register_passkey.json 401 (No autorizado)
send @ jquery.js:9940
ajax @ jquery.js:9521
o @ ajax.js:188
(anonymous) @ rsvp-DaQAFb0W.js:435
e @ rsvp-DaQAFb0W.js:451
A @ ajax.js:201
registerPasskey @ user.js:650
createPasskey @ user-passkeys.gjs:86
await in createPasskey
didConfirm @ user-passkeys.gjs:140
didConfirmWrapped @ dialog.js:134
_join @ index.js:788
join @ index.js:605
p @ index.js:152
(anonymous) @ index.js:250
submit @ confirm-session.gjs:84
await in submit
(anonymous) @ d-button.gjs:138
invoke @ index.js:264
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
end @ index.js:565
_runExpiredTimers @ index.js:869
setTimeout
setTimeout @ index.js:39
_installTimerTimeout @ index.js:912
_later @ index.js:823
later @ index.js:652
T @ index.js:562
_triggerAction @ d-button.gjs:135
click @ d-button.gjs:93
user-passkeys.gjs:104  {jqXHR: {…}, textStatus: 'error', errorThrown: ''}errorThrown: \"\"jqXHR: abort: ƒ (e)always: ƒ ()catch: ƒ (e)done: ƒ ()fail: ƒ ()getAllResponseHeaders: ƒ ()getResponseHeader: ƒ (e)jqTextStatus: \"error\"overrideMimeType: ƒ (e)pipe: ƒ ()progress: ƒ ()promise: ƒ (e)readyState: 4requestedUrl: \"/u/register_passkey.json\"responseJSON: {errors: Array(1)}responseText: \"{\\\"errors\\\":[\\\"The origin of the authentication request does not match the server origin.\\\"]}\"setRequestHeader: ƒ (e,t)state: ƒ ()status: 401statusCode: ƒ (e)statusText: \"error\"then: ƒ (e,i,n)[[Prototype]]: ObjecttextStatus: \"error\"[[Prototype]]: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()__proto__: (...)get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()
createPasskey @ user-passkeys.gjs:104
await in createPasskey
didConfirm @ user-passkeys.gjs:140
didConfirmWrapped @ dialog.js:134
_join @ index.js:788
join @ index.js:605
p @ index.js:152
(anonymous) @ index.js:250
submit @ confirm-session.gjs:84
await in submit
(anonymous) @ d-button.gjs:138
invoke @ index.js:264
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
end @ index.js:565
_runExpiredTimers @ index.js:869
setTimeout
setTimeout @ index.js:39
_installTimerTimeout @ index.js:912
_later @ index.js:823
later @ index.js:652
T @ index.js:562
_triggerAction @ d-button.gjs:135
click @ d-button.gjs:93
1 me gusta

Oh, hmm, esto es útil, pero los 401 pueden ser provocados por una miríada de razones. Consultaré con nuestro experto residente en passkeys.

1 me gusta

¿Puede asegurarse de que su sitio esté configurado para servir todo en https? La verificación del desafío de la clave de acceso requiere que todas las solicitudes pasen por https. Además, el dominio entre el navegador y el servidor debe coincidir exactamente. Si hay una discrepancia en algún lugar, la verificación fallará.

Tenemos una configuración para esto, force_https, puede probarla, puede ayudar (aunque tenga cuidado, también podría bloquearlo si el servidor no está configurado correctamente).

2 Me gusta

este es mi app.yml
estoy usando un proxy inverso con OpenResty (basado en nginx)

expose:
  - "6180:80"   # http
  - "6443:443" # https
  - "587:587"

no puedo usar mi sitio por el puerto https 6443

así que solo configuré el proxy inverso http

esta es mi configuración de OpenResty

server {
    listen 80 ;
    listen 443 ssl http2 ;
    server_name forum.beginner.center;
    index index.php index.html index.htm default.php default.htm default.html;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    access_log /www/sites/forum.beginner.center/log/access.log main;
    error_log /www/sites/forum.beginner.center/log/error.log;
    location ^~ /.well-known/acme-challenge {
        allow all;
        root /usr/share/nginx/html;
    }
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }
    ssl_certificate /www/sites/forum.beginner.center/ssl/fullchain.pem;
    ssl_certificate_key /www/sites/forum.beginner.center/ssl/privkey.pem;
    ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497 https://$host$request_uri;
    proxy_set_header X-Forwarded-Proto https;
    add_header Strict-Transport-Security "max-age=31536000";
    include /www/sites/forum.beginner.center/proxy/*.conf;
}

esta es la configuración del proxy inverso

location ^~ / {
    proxy_pass http://127.0.0.1:6180;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_http_version 1.1;
    add_header X-Cache $upstream_cache_status;
    add_header Cache-Control no-cache;
    proxy_ssl_server_name off;
    proxy_ssl_name $proxy_host;
    add_header Strict-Transport-Security "max-age=31536000";
}

hola, ¿alguien puede ayudarme?

Disculpe la demora. El problema aquí está efectivamente relacionado con su proxy. No puedo decir exactamente qué es, pero uno de los nombres de dominio, el protocolo (http o https) y el puerto están interfiriendo.

Las Passkeys verifican que el frontend y el backend se ejecuten en el mismo dominio, protocolo y puerto. Si hay una discrepancia en alguno de estos, obtendrá un error como este.

En la CLI de Rails, ¿puede intentar esto:

DiscourseWebauthn.origin

y compararlo con la URL que usa para acceder al sitio en el navegador? Los dos deberían coincidir.

La función de passkey del usuario funcionó cuando habilité forzar https

referencia

2 Me gusta

Según entiendo el Estándar Webauthn para Passkey, este se basa en una conexión segura entre la Parte Confiable (Discourse) y el Cliente (Navegador o dispositivo móvil) y el Autenticador (por ejemplo, una yubikey). Por lo tanto, necesitamos https para la comunicación que proviene de la aplicación Discourse. Forzar https puede ser la solución, pero un encabezado para
proxy_set_header X-Forwarded-Proto https;
también podría ser suficiente. Si forzar https ayuda (lo cual se recomienda de todos modos), todo estará bien.

1 me gusta

No sé cómo configurar proxy_set_header X-Forwarded-Proto en app.yaml.