<p>I wanted to discuss handling auth in Go, I am creating a webapp which requires authentication, so far I didn't find one method to rule them all, I have found multiple approaches, but I have come up to this mode of auth, before I embark on the journey I want feedback</p>
<ol>
<li><p>using forms we take username/pwd</p></li>
<li><p>we read the cookie for session ID, check in our DB if an active session is present for that ID, if so, fine, otherwise set a cookie with the session ID</p></li>
<li><p>find the userID from the sessionID in case of cookie | from the username supplied</p></li>
<li><p>populate stuff based on the userID</p></li>
</ol>
<p>In this case I do not think we'd require a global manager of any sort.
Also rather than storing this session related info in a sql database, we can store it in a redis or something else.</p>
<p>Do we need the context package? or the gorilla/sessions?</p>
<p>I am sorry if these questions are rudimentary, I am pretty new to this domain and I'd like to learn things <em>without</em> previous biases.</p>
<p>Thank you!</p>
<p>EDIT: <a href="http://github.com/thewhitetulip/Tasks">http://github.com/thewhitetulip/Tasks</a> is the project which I am wanting to apply use auth to.</p>
<hr/>**评论:**<br/><br/>iends: <pre><p>Is this a single page application? Are there multiple services you may be authenticating with? How complex are your permissions and roles?</p>
<p>What you suggest seems reasonable.</p>
<p>Another method I've used quite successfully is to generate a JWT token (good info at jwt.io) that contains a list of specific grants that can easily be verified via HMAC, or public/private key signing. (The cool thing about using public/private keys is that only your auth service needs to know the private key so if a minor service is compromised somebody cannot generate keys...but this has CPU overhead on each request.) Then the only problem is short-lived token revocation and sharing these revocations between each service (or making I/O call to look up to see if a token been revoked).</p></pre>thewhitetulip: <pre><p><a href="http://github.com/thewhitetulip/Tasks" rel="nofollow">http://github.com/thewhitetulip/Tasks</a>
This is my application :-)</p>
<p>No there aren't multiple services I am authenticating with, the application is a todo list manager and is quite simple at that, we take tasks and perform few operations on top of it.</p>
<p>Yes, I am planning to do JWT so that if I write an android app for the project, it'll use JWT. I haven't got any good tutorial explaining JWT in Go, can you please guide me?</p></pre>ecmdome: <pre><p>Well if you're storing the session data in Redis you could get rid of the sessions package and just include your session token in each request.</p>
<p>Although I would personally still use a context package... Otherwise you would be hand crafting something similar anyway.</p>
<p>I used gorilla/context which is great but I'm looking to switch over to the <a href="https://godoc.org/golang.org/x/net/context" rel="nofollow">x/net/context</a> package.</p></pre>thewhitetulip: <pre><p>I am sorry, I am utterly naive when it comes to context packages, Can't I work without them for my app?</p>
<p>yes that was my plan, instead of holding session info in a global map like the gorilla/session does, we can store it in redis/boltdb and read the cookie for each request.</p></pre>ecmdome: <pre><p>I probably won't explain this the best way. But context package is used to pass information between functions that call each other.</p>
<p>The description in that link offers a much better explanation.</p></pre>theexcellentninja: <pre><p>Last time I had to handle authentication in a Go webapp, I used pretty much your approach, but with the added note of all stored passwords was of course salted and hashed. </p>
<p>For storage, I used Bolt since I needed something simple and preferable single-file. Your use-case might differ.</p>
<p>Now, to be fair, this was a non-critical application for use in a semi-closed group (me, friends, friends of friends) but it serves its purpose. </p>
<p>Preferably, you don't store passwords or hashes at all and instead dump the problem on Google/Facebook/Twitter/Github/Whatever using OAuth, but this might not be applicable depending on what you are doing.</p></pre>thewhitetulip: <pre><p><a href="http://github.com/thewhitetulip/Tasks" rel="nofollow">http://github.com/thewhitetulip/Tasks</a> This is my app</p>
<p>I do not want to dump the problem on OAuth because my app is going to be self hosted and I'd like the app to be functioning totally offline, otherwise if I had regular Internet I'd use trello :P</p>
<p>Coming to one question I had posted above, in this scenario which you have validated for me, do i need to use the context package or the gorilla sessions?</p>
<p>what should be my approach to hit the boltdb be? I was also contemplating using boltdb since it is pure Go unlike Redis. </p>
<p>For each sessionID validation do I need to hit the bolt db? I am not aware of the cost of a read operation of a key value store as opposed to a sql database, but I assume it must be crazy fast and not consuming much resources.</p>
<p>So ultimately, I do not need to use gorilla/sessions right? the approach I wrote in the question will work yes?</p></pre>theexcellentninja: <pre><p>I used gorilla sessions and securecookie so I definitely recommend them.
Something I did not mention was that my sessions "DB" was a gorilla sessions Store. I only used Bolt to store user credentials and other information gathered.
But nothing stops you from using the Bolt DB as you described. You could probably even integrate it into gorilla if you choose to by implementing Store interface or find a exiting somewhere online.</p>
<p>I did not really need Context or anything like it (the only point of the project was adding authentication by reverse proxy to a existing site)
Never needed it personally, so I can not help you there. </p>
<p>With BoltDB, you probably want to treat it like what it is, a bucket-based single file DB. So primarily read operations since they can execute concurrently. Have a clear heirachy in the data you do not have relations in the same way as a SQL DB.
Since I only had the occational writes during logins, registrations and password changes, this was not a problem.
On the other hand, I have heard of lots of people use Bolt for some pretty big projects, so I would not worry about performance of it in the first hand for this project.</p></pre>thewhitetulip: <pre><p>True, I'll use Bolt to store the user credentials + session information</p>
<p>everything else is SQL DB, I do not think I'll require context, But I do not understand where gorilla/sessions comes into picture, can't I write a custom session manager using boltDB?</p>
<p>Using SecureCookie I totally agree because there is no other option on the browser side to store the sessionID</p></pre>robvdl: <pre><p>Use Gorilla sessions because it provides a pluggable Store interface, and adapters already exist for Redis or BoltDB, so writing one yourself is not needed and a probably a bit of a waste of time. Writing a session library yourself is probably not a good idea either because sessions are encrypted using an algorithm called HMAC, and trying this yourself will probably lead to security vulnerabilities in your app, it's a solved problem, so don't try to reinvent the wheel yourself basically.</p>
<p>I suggest you should probably really look into middlewares and contexts, when I did sessions in my own app I used the Gin framework and the session middleware from gin-contrib (which essentially is just a middleware that wraps Gorilla sessions), I used the Redis session store. However, you can achieve all of this without a framework just as well, you really don't need Gin for this at all.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传