discuitnet / discuit

A free and open-source community discussion platform.
https://discuit.net
GNU Affero General Public License v3.0
385 stars 40 forks source link

Login issue with problem not getting SID #41

Closed brightly-p closed 2 months ago

brightly-p commented 4 months ago

Issue

Login issue with problem not getting Session Cookie Name (SID)

Description

The current server configuration is as follows, where there is a Discuit server and Client 1 is connected through the router. Discuit Server (192.168.0.10) --- Router (Switch) ---- Client 1 (192.168.0.67)

After the Discuit server build and connecting from client 1, the site was accessed normally. (In my case, Client 1 use192.168.0.10:80 to access discuit server)

Build and run command

$ mv config.default.yaml config.yaml
$ ./build.sh
$ ./discuit -migrate
$ sudo ./discuit -serve
  2024/02/20 04:32:39 Starting server on :80

When registering from Client 1, it was successfully saved in the DB. In MariaDB, select the 'dbName' database from the 'config.yaml' file and use 'SELECT * FROM users;' It was confirmed.

However, login did not work properly. It seemed that the client's SID could not be retrieved from the Discuit server terminal.

Just in case, I opened a browser in the server environment, accessed localhost:80, and tried logging in. In localhost, not only did I log in normally, but I was able to create a community and write as well.

I am not familiar with web (front-/back-end) and network systems. What part should I change?

Environment

Code Snippets

config.yaml

addr:                     # I just keep it blank
sessionCookieName: SID

# MariaDB configuration:
dbAddr: 127.0.0.1         # Required
dbUser: root              # Required
dbPassword: discuit       # Required
dbName: discuit           # Required

Logs in server terminal

Case of client 1

2024/02/20 02:35:45 took=3.77775ms url=/api/_login ip=192.168.0.67 method=POST sid= 
2024/02/20 02:35:48 took=4.338343ms url=/api/posts?sort=hot ip=192.168.0.67 method=GET sid=

Case of localhost (Use Firefox in server system)

2024/02/20 02:41:00 took=2.810934ms url=/ ip=127.0.0.1 method=GET sid=seCh19BCY1cgwKKERFCSJr6ZKyreJz3AhlJF
2024/02/20 02:41:01 took=14.028048ms url=/service-worker.js ip=127.0.0.1 method=GET sid=seCh19BCY1cgwKKERFCSJr6ZKyreJz3AhlJF
2024/02/20 02:41:01 took=3.299818ms url=/api/_initial ip=127.0.0.1 method=GET sid=seCh19BCY1cgwKKERFCSJr6ZKyreJz3AhlJF
2024/02/20 02:41:03 took=688.271µs url=/service-worker.js ip=127.0.0.1 method=GET sid=seCh19BCY1cgwKKERFCSJr6ZKyreJz3AhlJF
2024/02/20 02:41:03 took=7.099999ms url=/api/posts?sort=hot ip=127.0.0.1 method=GET sid=seCh19BCY1cgwKKERFCSJr6ZKyreJz3AhlJF
Codycody31 commented 4 months ago

This probably isn't the case, but what if you change addr to be the ip of the server and then the port, or see from the server and attempt via the same way that a client may? I don't think this is the issue but could be worth a try to see what happens

brightly-p commented 4 months ago

@Codycody31 I tried changing 'addr' to 'addr: 192.168.0.10:80' in 'config.yaml', but it still didn't work.

I searched for various methods, but came to the following conclusion. (reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)

When I checked the network packet in Client1's browser (Chrome), it seems that my cookie was blocked because the Discuit server uses a secure cookie, as shown in the following picture.

image

\ Through localhost, it doesn't seem to matter whether the cookie is secure or not. This was because I wasn't using https. \ I modified the code below to temporarily test Discuit.

discuit/internal/sessions/sessions.go

141 cookie, err := r.Cookie(rs.CookieName)
142 if !s.CookieSet && (err == http.ErrNoCookie || cookie.Value != s.ID) {
143     http.SetCookie(w, &http.Cookie{
144         Name:     rs.CookieName,
145         Value:    s.ID,
146         Secure:   true,
147         HttpOnly: true,
148         Path:     "/",
149         Expires:  time.Now().UTC().Add(expires),
150         SameSite: http.SameSiteLaxMode,
151     })
152     s.CookieSet = true
153 }

line 146 Secure: true -> Secure: false

141 cookie, err := r.Cookie(rs.CookieName)
142 if !s.CookieSet && (err == http.ErrNoCookie || cookie.Value != s.ID) {
143     http.SetCookie(w, &http.Cookie{
144         Name:     rs.CookieName,
145         Value:    s.ID,
146         Secure:   false,
147         HttpOnly: true,
148         Path:     "/",
149         Expires:  time.Now().UTC().Add(expires),
150         SameSite: http.SameSiteLaxMode,
151     })
152     s.CookieSet = true
153 }

Then I built again and did './discuit -hard-reset' When I connected again from Client 1 and logged in, the SID was read normally and the login worked well.

2024/02/20 07:21:43 took=5.726453ms url=/api/_user ip=192.168.0.67 method=GET sid=XFf1ApKci0fyzn6pR03bbrN4iE7Uv6y3NG2A
2024/02/20 07:21:48 took=7.813031ms url=/api/_user ip=192.168.0.67 method=GET sid=XFf1ApKci0fyzn6pR03bbrN4iE7Uv6y3NG2A
Codycody31 commented 4 months ago

Ah, that would explain it. Maybe we add another flag in the config for it. Or do you think it could be based of addr. For example if 443 or https use secure

Codycody31 commented 4 months ago

Never mind, at least from what I can see, in the current state it may not be possible, as that would require the config which doesn't seem to be passed from main to session. But this could cause other issues, for example, if discuit is serving on HTTP it would not correctly work due to the cookie not being set (I haven't tested but I think this is what would happen).

it's probably up to previnder and the others for how this could/would be solved

brightly-p commented 4 months ago

@Codycody31 Thank you for your opinion. I tried running the server by changing 'addr' in config.yaml to '192.168.0.83:443', but I still had the SID problem.

Checking the main.go file below, it seems that in addition to simply changing the port number to 443, I need to set the TLS/SSL certification file and key in config.yaml.

discuit/main.go (line: 110)

    if conf.CertFile != "" {
        // Running HTTPS server.
        //
        // A server to redirect traffic from HTTP to HTTPS. Started only if the
        // main server is on port 443.
        if conf.Addr[strings.Index(conf.Addr, ":"):] == ":443" {
                    ... 
        }
        if err := server.ListenAndServeTLS(conf.CertFile, conf.KeyFile); err != nil {
            log.Fatal("Error starting server (TLS): ", err)
        }
    } else {
        // Running HTTP server.
        if err := server.ListenAndServe(); err != nil {
            log.Fatal("Error starting server: ", err)
        }
    }

I don't currently have a domain, and I'm not the administrator of the web server, so I didn't proceed any further.

As you said, perhaps the section about secure cookies in the session settings when using http should be added or modified in the discuit.

previnder commented 4 months ago

Yep, the Set-Cookie header with the Secure attribute is the problem, as it only works over https (and localhost). A quick workaround for this would be using a self-signed SSL certificate.