Login Procedure

I made a draft of a login procedure for a web application and I am looking for advice or feedback if this a good way to do a login procedure.

I have already a Go REST API and is interacting with a Postgresql database.

No I am thinking of create an Centralized Authentication Server using Go that only handle everything regarding authentication, validation and gathering information and create an Authentication Token to use in the web application later.

Here is a visualization of my thoughts

My questions are:

  1. Am I overthinking this?
  2. Is this a secure way to login?
  3. Any tip which tools I can use?
  4. Any other comments welcome…

Regarding tips on tools to use i would recommend using Json web tokens (JWT) for your authentication.

1 Like

Probably. :slight_smile: For a small app/site, I’d start small. There’s no reason to have a separate microservice / database for authentication unless you’ve scaled to the point where you NEED that.

As long as you’re transmitting everything over TLS and checking the signing mode of your JWT along with a secure signing secret, yes. Never store anything sensitive in a JWT though.

Sure.

  • For password hashing, use bcrypt. The default cost of 10 is probably fine for most cases. With hashing, you’re basically betting that a hacker won’t spend the amount of resources required to brute-force your passwords (in the event that they get ahold of the hash in the first place). Like with the default cost I believe it would take something like 500 days with modern hardware to brute force it. Check this out for more information.
  • For your tokens, take a look at this JWT introduction. And you can use golang-jwt/jwt or something similar.

Here’s the general flow:

  • On user create, store hashed password (hash using bcrypt).
  • On login attempt, but sure to rate-limit it somehow (this could be DDOS protection in your firewall, not necessarily in your API). Check for existence of email. If exists, compare password to hashed passworrd in DB (example in the link above).
  • If user is authorized, issue a signed JWT token.
  • On subsequent calls to authorized routes, check the token along with the signing algorithm and signing secret. As long as you’re checking those things, you can be sure that you issued the token and it has not been modified since you issued it. In general, the token would include the users’ email address or some way of identifying them (like an ID in your database). I also sometimes include things like user roles if I have an app that has role-based auth.
2 Likes

Take a look over the following example. Encryption scheme is a little obsolete but you can easy extend it with bcrypt or something else.

1 Like

Nice. That looks like a great starting point. Minor note: be sure to check for errors on config JSON decode here. That has bitten me before. Not sure what /geosoft1/json is doing in that Decode function so it might be doing just that.

@Sibert you could refactor it to use encoding/json and check for errors like so:

file, err := os.Open(filepath.Join(folder, "config.json"))
if err != nil {
	log.Fatalln(err)
}
if err = json.NewDecoder(file).Decode(&config); err != nil {
	log.Fatalln(err)
}
1 Like

Hey Dean,

Indeed, in time, I gave up on that package that actually contained the code you just posted. Thank you for letting me know this. I will update the code.

1 Like

No prob. You could also update it to Go Modules. And final note: I wonder if build flags are really the way to go for auth configuration. You could refactor that to use bcrypt and at the same time move that to your config file. The part about that that scares me is: if you rely on build flags, an incorrect build could bork a deploy. There’s also code that doesn’t need to be duplicated (e.g. sqlUserCount is the same code regardless of your password storage scheme). I’ll stop giving unsolicited feedback now. :wink:

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.