为了账号安全,请及时绑定邮箱和手机立即绑定

ory kratos csrf cookie 未在 nginx ssl 后面发送

ory kratos csrf cookie 未在 nginx ssl 后面发送

Go
肥皂起泡泡 2022-09-05 09:15:17
我在docker中使用Go和ory kratos,在localhost上的我的机器上一切正常。身份验证工作,所有cookie都已发送和设置,我可以从SPA调用我的后端并进行身份验证。问题是,在后面的实时服务器上,显然没有从我的js客户端发送一个cookie(仅发送而不是cookie),并且它在功能中失败,cookie丢失错误。nginxsslory_kratos_sessionxxx_csrf_token它使用官方的go sdk:kratos-client-goGo 身份验证必需的中间件func ExtractKratosCookiesFromRequest(r *http.Request) (csrf, session *http.Cookie, cookieHeader string) {    cookieHeader = r.Header.Get("Cookie")    cookies := r.Cookies()    for _, c := range cookies {        if c != nil {            if ok := strings.HasSuffix(c.Name, string("csrf_token")); ok {                csrf = c            }        }    }    sessionCookie, _ := r.Cookie("ory_kratos_session")    if sessionCookie != nil {        session = sessionCookie    }    return}func AuthRequired(w http.ResponseWriter, r *http.Request) error {    csrfCookie, sessionCookie, cookieHeader := ExtractKratosCookiesFromRequest(r)    if (csrfCookie == nil || sessionCookie == nil) || (csrfCookie.Value == "" || sessionCookie.Value == "") {        return errors.New("Cookie missing")    }    req := kratos.PublicApi.Whoami(r.Context()).Cookie(cookieHeader)    kratosSession, _, err := req.Execute()    if err != nil {        return errors.New("Whoami error")    }        return nil}我的 js http 客户端有选项:.credentials: 'include'在devtools面板中,我只看到1个cookie()在注册/登录后。ory_kratos_session因此,失败的是请求仅发送而不是cookie(在kratos模式下工作,并且cookie在devtools面板中是可行的)ory_kratos_sessionxxx_csrf_tokenlocalhost--dev
查看完整描述

2 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

我相信你的kratos配置不正确。该属性应该是请求源自的 url,例如 而不是您的本地主机。serve.public.base_urlhttps://example.com/kratos/http://127.0.0.1:4433

另外,只是一个建议,您的管理端点永远不应该向公众公开,您的后端服务应该在内部网络上请求管理员URL(例如,在Docker内部或localhost上)。你应该从nginx中删除。serve.admin.base_urlhttp://127.0.0.1:4434

nginx配置对我来说似乎是正确的。我相信你只需要这个就可以了:

location /kratos/ {
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://127.0.0.1:4433;
    }


查看完整回答
反对 回复 2022-09-05
?
12345678_0001

TA贡献1802条经验 获得超5个赞

我确实设法解决了这个问题,它在生产中没有标志的情况下工作正常,即使在重新启动服务和更改所有内容后也不会搞砸。--dev


也许它甚至是我的反应形式,我使用defaultValue作为csrf令牌输入


现在,每当 window.location url 更改或csrf_token更改时,它都应该使用最新的值作为csrf_token


const [csrf, setCsrf] = React.useState('');


useEffect(() => {

  if (flowResponse !== null) {

    const csrfVal = flowResponse?.ui?.nodes?.find?.(n => n.attributes.name === 'csrf_token')?.attributes.value;

    setCsrf(csrfVal);

  }

}, [flowResponse, csrf]);


<input type='hidden' name='csrf_token' value={csrf} readOnly required />

最糟糕的是,它也可能是一个尾部斜杠或如此小的东西,我不确定究竟是什么原因造成的。


在这里,所有人都发布了所有适合我的配置:


可能是我以前尝试过这个kratos网址 http://127.0.0.1:4433 或 http://kratos:4433,但它不起作用(即使我在这3个之间切换哈哈)


init kratos client

conf := kratos.NewConfiguration()

conf.Servers[0].URL = "https://example.com/kratos/"

kratosClient := kratos.NewAPIClient(conf)

kratos.yml

version: v0.6.2-alpha.1


dsn: postgres://test:test@postgresd:5432/test?sslmode=disable&max_conns=20&max_idle_conns=4


serve:

  public:

    base_url: https://example.com/kratos/

    cors:

      enabled: true

      debug: true

      allow_credentials: true

      options_passthrough: true

      max_age: 0

      allowed_origins:

        - https://example.com

      allowed_methods:

        - POST

        - GET

        - PUT

        - PATCH

        - DELETE

        - OPTIONS

      allowed_headers:

        - Authorization

        - Cookie

        - Origin

        - X-Session-Token

      exposed_headers:

        - Content-Type

        - Set-Cookie

  admin:

    base_url: http://127.0.0.1:4434/


selfservice:

  default_browser_return_url: https://example.com

  whitelisted_return_urls:

    - https://example.com

    - https://example.com/dashboard

    - https://example.com/auth/login

  methods:

    password:

      enabled: true

    oidc:

      enabled: false

    link:

      enabled: true

    profile:

      enabled: true

  flows:

    error:

      ui_url: https://example.com/error

    settings:

      ui_url: https://example.com/dashboard/profile

      privileged_session_max_age: 15m

    recovery:

      enabled: true

      ui_url: https://example.com/auth/recovery

      after:

        default_browser_return_url: https://example.com/auth/login

    verification:

      enabled: true

      ui_url: https://example.com/auth/verification

      after:

        default_browser_return_url: https://example.com

    logout:

      after:

        default_browser_return_url: https://example.com

    login:

      ui_url: https://example.com/auth/login

      lifespan: 10m

    registration:

      lifespan: 10m

      ui_url: https://example.com/auth/registration

      after:

        password:

          hooks:

            - hook: session

          default_browser_return_url: https://example.com/auth/login

        default_browser_return_url: https://example.com/auth/login

        oidc:

          hooks:

            - hook: session


secrets:

  cookie:

    - veRy_S3cRet_tHinG


session:

  lifespan: 24h

  cookie:

    domain: example.com

    same_site: Lax

    path: /           

// <- i didn't have path before, not sure if it changes anything but it works (before csrf cookie had path /kratos and now when it works it has path /, same as session_cookie)


hashers:

  argon2:

    parallelism: 1

    memory: 128MB

    iterations: 1

    salt_length: 16

    key_length: 16


identity:

  default_schema_url: file:///etc/config/kratos/identity.schema.json


courier:

  smtp:

    connection_uri: smtp://user:pwd@smtp.mailtrap.io:2525

    from_name: example

    from_address: office@example.cpm


watch-courier: true


log:

  level: debug

  format: text

  leak_sensitive_values: true

nginx.conf

server {

    server_name example.com www.example.com;


    location / {

       root /var/www/public;

       try_files $uri $uri/ /index.html;

    }


    location /api/ {

      proxy_pass http://127.0.0.1:3001; // backend api url

      proxy_http_version 1.1;

      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 X-Forwarded-Port $server_port;

      proxy_set_header x-forwarded-proto $scheme;

      proxy_set_header Upgrade $http_upgrade;

      proxy_set_header Connection 'upgrade';

      proxy_cache_bypass $http_upgrade;

    }


    location /kratos/ {

      proxy_pass http://127.0.0.1:4433/;  // kratos public url

      proxy_http_version 1.1;

      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 X-Forwarded-Port $server_port;

      proxy_set_header x-forwarded-proto $scheme;

      proxy_set_header Upgrade $http_upgrade;

      proxy_set_header Connection 'upgrade';

      proxy_cache_bypass $http_upgrade;

    }

       

    listen [::]:443 ssl ipv6only=on; # managed by Certbot

    listen 443 ssl; # managed by Certbot

    certs...

}


server {

    if ($host = www.example.com) {

        return 301 https://$host$request_uri;

    } # managed by Certbot


    if ($host = example.com) {

        return 301 https://$host$request_uri;

    } # managed by Certbot


   listen 80 default_server;

   listen [::]:80 default_server;

   server_name example.com www.example.com;

   return 404; # managed by Certbot

}


查看完整回答
反对 回复 2022-09-05
  • 2 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信