<hr/>**评论:**<br/><br/>icholy: <pre><p>I use JWT <a href="https://jwt.io/" rel="nofollow">https://jwt.io/</a> which contain the user's permissions. </p>
<p>edit: why the hell is this getting downvoted?</p></pre>tmornini: <pre><p>Token based authentication is the bees' knees. :-)</p></pre>icholy: <pre><p>Except there's no easy way to force a logout :/</p></pre>tmornini: <pre><p>Sure there is!</p>
<p>Use memcached or redis to store the token as a key.</p>
<p>If it's there, the token is verboten.</p>
<p>Simple!</p></pre>icholy: <pre><p>Defeats the purpose of using a token in the first place. </p></pre>tmornini: <pre><p>I'd agree that it lessens part of the benefit.</p>
<p>Upside: no need to hit the DB on unauthenticated or unauthorized tokens -- fantastic under DDOS attacks.</p>
<p>Downside: need to hit an extremely low latency, high throughput store on authenticated and authorized (the most common case, to be sure) tokens -- but no need to store anything other than the key (or a hash of the key) in the blacklist.</p></pre>icholy: <pre><blockquote>
<p>Upside: no need to hit the DB on unauthenticated or unauthorized tokens -- fantastic under DDOS attacks.</p>
</blockquote>
<p>I don't understand. Why would it need to hit the DB?</p></pre>tmornini: <pre><p>If you're not using token based auth, then you need to authenticate and authorize against data which is almost universally stored in a DB of some sort.</p>
<p>Perhaps I should have said datastore? If that's the confusion, apologies.</p></pre>icholy: <pre><p>You'd only need to hit the DB once, on login. At that point you just load the user's data into redis/memcached with their session id as the key.</p></pre>tmornini: <pre><p>Yes, I should have said data store, which includes redis/memcached.</p></pre>metamatic: <pre><p>Give the token an expiry timestamp. When you check the token, if it's valid you issue a new one with the expiry time extended. To force a logout, you stop issuing new tokens.</p></pre>pvsukale1: <pre><p>can you explain please?</p></pre>icholy: <pre><p>If you're using sessions, then the client stores a sessions id. On the server-side you have some session store (redis) which maps the session id to the user's session data.</p>
<p>Every time a client makes a request, you use its session id to lookup the corresponding session data (permission data in your case). If you want to log them out, you just delete the entry in the session store so the client's session id becomes invalidated (doesn't point to anything).</p>
<p>Tokens, on the other hand, are completely self contained. They have all the user's data (id, permissions, etc ...). To prevent the user from modifying his own permissions, the token is signed using a key. Therefore, if someone changed his own permissions in the token, the signature is invalidated and it doesn't work anymore.</p>
<p>Whenever a client makes a request with a token, the server just has to validate the signature and then (assuming the signature is valid) use the permissions in the token.</p>
<p>The problem is that, if you want to log someone out, you have no session on the server you can delete. You have to wait until they make another request to clear their cookie (or w/e mechanism you're using). You can always change the key used to sign the tokens, but that invalidates everyone's tokens.</p></pre>pvsukale1: <pre><p>thank you for the thorough explanation. you mentioned that "Give the token an expiry timestamp. When you check the token, if it's valid you issue a new one with the expiry time extended. To force a logout, you stop issuing new tokens."
Is this method efficient or does it have any trade-offs?</p></pre>icholy: <pre><p>If you absolutely need to be able to force someone to log out, just use good old sessions. Save yourself some headaches. </p></pre>pvsukale1: <pre><p>I meant how are you restricting access to unauthenticated users to users' personal pages ?
middleware or something?</p></pre>kpurdon: <pre><p>Yes, middleware that checks whatever means of auth your using (token based or session based). Basically the middleware says given request to page A does (session or token) have access to this? Yes - Continue. No - Not Authorized</p></pre>thepciet: <pre><p>You could have a map[Person]map[Page]Permissions and ask it if the person has permissions for the page.</p>
<pre><code>type Person string
type Page string
type Permissions bool
</code></pre>
<p>is a simple way to concretely type the map. You'll have to write the allocation (make) and manage concurrency (sync.RWMutex).</p>
<p>The way I do it though is to ask for what contents I'd expect on the page. "I" in this context for my app is a session ID (for web, held as a browser cookie on the client) that is validated on each request, in my http package handlers. So the client always asks for simple pages and the appropriate data is mapped back to them from the server.</p></pre>EtoWato: <pre><p>what library are you using for networking/routing?</p></pre>pvsukale1: <pre><p>gorilla mux</p></pre>kiwihammond: <pre><p>I made an application with gorilla mux and found that I had at least two ways of handling my authentication middleware.</p>
<p>Firstly, using no other libraries, you can wrap your handlers in the middleware functions, to have something like </p>
<pre><code>router.HandleFunc("/log", authmiddleware(ListLogHandler)).Name("ListLog")
</code></pre>
<p>Your authmiddleware function would have the signature
func authmiddleware(h http.Handler) http.Handler </p>
<p>But, I found that putting this on every function when I had lots and lots of URLs (and when I started gaining lots of middleware functions) became extremely unweildy extremely quickly.</p>
<p>So, I found that <a href="https://github.com/carbocation/interpose" rel="nofollow">interpose</a> combines reasonably well with gorilla/mux, enabling me to have somewhat saner middleware management.</p>
<p>With this, I end up with something that looks like this:</p>
<pre><code>middle := interpose.New() //This contains all routing and middleware.
router = mux.NewRouter()
router.HandleFunc("/", loginPageHandler).Methods("GET")
... (rest of unprotected URLs)
...
middle.UseHandler(router)
//super secret auth router time
authRouter := mux.NewRouter().PathPrefix("/secret").Subrouter()
authRouter.HandleFunc("/account", accountHandler)
...(other protected urls)
...
authMiddle := interpose.New()
authMiddle.Use(ensureAccountMiddleware)
authMiddle.UseHandler(authRouter)
router.PathPrefix("/secret").Handler(authMiddle)
</code></pre>
<p>This works reasonably well, but I still found it somewhat frustrating.</p>
<p>For my next application I tried using <a href="https://github.com/gocraft/web" rel="nofollow">gocraft web</a> instead of gorilla, which I found way cleaner and easier to use. If you're interested in gocraft web, I have an open source <a href="https://github.com/kiwih/heyfyi" rel="nofollow">complete example web app</a> that you can look at to see how it is structured.</p></pre>pvsukale1: <pre><p>thank you for the example web app .I was looking for something like this.
that structure will be really helpful. as this is my first web app and I am just learning through small examples in the books. This one is really helpful for the big picture. </p></pre>kiwihammond: <pre><p>No worries - I was exactly the same way! </p>
<p>Feel free to post any issues or questions to github and good luck with your first app!</p></pre>dAnjou: <pre><p>The terms are <em>authentication</em> for who a user is and <em>authorization</em> for what a user is allowed to do. "access control" is too broad and not really a term in web dev.</p></pre>pschlump: <pre><p>I have implemented Secure Remote Password (SRP 6a) - this allows key exchange without ever sending the password across the wire. Once keys are exchanged I use 256-bit AES encryption on every RESTful call. This sets on top of HTTPS/TLS. Every request/response is digitally singed. I am working on documentation and examples. See <a href="http://www.go-ftl.com/" rel="nofollow">http://www.go-ftl.com/</a></p></pre>pvsukale1: <pre><p>How does it work? like regular SSL? </p></pre>pvsukale1: <pre><p>and when the documentation will be completed ? any estimate? this project looks really interesting!</p></pre>i_like_pnut_butter: <pre><p>I use jwt's to store session information, such as what the user can access and the expiry time. I'm also using gorilla mux as the router and negroni as the middleware library. </p>
<p><a href="https://github.com/auth0/go-jwt-middleware" rel="nofollow">https://github.com/auth0/go-jwt-middleware</a> hooks straight into your negroni middleware with some good defaults and customising is really easy.</p>
<p>The above library is a wrapper around the excellent <a href="https://github.com/dgrijalva/jwt-go" rel="nofollow">https://github.com/dgrijalva/jwt-go</a> which uses.to be the standard for implementing JWTs in golang. </p></pre>pvsukale1: <pre><p>how did you implement a log out?</p></pre>i_like_pnut_butter: <pre><p>Logging out is achieved by removing the claim from the token and returning. In my case the service was acting as a proxy between the user and multiple different APIs, so although the user is given a single token, it claims for each.</p>
<p>If the same token without the claim is resent we can check that the claim is no longer valid.</p></pre>cawdrizzle: <pre><p><a href="http://stackoverflow.com/questions/25218903/how-are-people-managing-authentication-in-go" rel="nofollow">http://stackoverflow.com/questions/25218903/how-are-people-managing-authentication-in-go</a></p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传