dingoblog / dingo

Blog engine written in Go
MIT License
284 stars 37 forks source link

[WIP] Authorization for api routes using a X-SESSION-ID header instead of a cookie #26

Closed samdfonseca closed 8 years ago

samdfonseca commented 8 years ago

This PR is related to and dependent on https://github.com/dinever/dingo/pull/17.

This provides authorization for api routes using a X-SESSION-ID header instead of a cookie, making it easy for front end frameworks to access them.

$ curl -s -X POST -d 'email=admin@example.com&password=password123' http://localhost:8000/auth | jq .
{
  "user_role": 0,
  "user_id": 1,
  "user_email": "admin@example.com",
  "expiration": 1462262017,
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyRW1haWwiOiJzYW1mb25zZWNhQHV0ZXhhcy5lZHUiLCJVc2VySUQiOjEsIlVzZXJSb2xlIjowLCJleHAiOjE0NjIyNjIwMTd9.I_vuPtRe-mRTRh9-iSMNL7Ou4PJzgv1TLAlPz3oYKCbnEodYwYBjy_fiTB0mshEovksbn2f_STPZPgFjd1JASP5yR1ZQwccUujsZ3gW-tyK0K96qgP017l_rJIax2vjj3GjHgaMWrLPcEyPMFhdbrsS5GDrTadkxcTtlbBTKglemFBjjRB7p27QcPZvio3z4Bk7NsWTJGtkPid02DNN4LDiyRmyrbTPGAyhL_GZLVuLBpy2aMequ-L3kqEqjS-IkSXgPfxZ-gjX109bg2p3q_F5Y5fYU-j_DdIGGwzrWlUe6xyxkdTlitiwop3VF8kf0Eb_Z0NwPjYDRcO9OoKc7pw"
}

$ curl -s -X GET -H 'X-SESSION-TOKEN:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyRW1haWwiOiJzYW1mb25zZWNhQHV0ZXhhcy5lZHUiLCJVc2VySUQiOjEsIlVzZXJSb2xlIjowLCJleHAiOjE0NjIyNjIwMTd9.I_vuPtRe-mRTRh9-iSMNL7Ou4PJzgv1TLAlPz3oYKCbnEodYwYBjy_fiTB0mshEovksbn2f_STPZPgFjd1JASP5yR1ZQwccUujsZ3gW-tyK0K96qgP017l_rJIax2vjj3GjHgaMWrLPcEyPMFhdbrsS5GDrTadkxcTtlbBTKglemFBjjRB7p27QcPZvio3z4Bk7NsWTJGtkPid02DNN4LDiyRmyrbTPGAyhL_GZLVuLBpy2aMequ-L3kqEqjS-IkSXgPfxZ-gjX109bg2p3q_F5Y5fYU-j_DdIGGwzrWlUe6xyxkdTlitiwop3VF8kf0Eb_Z0NwPjYDRcO9OoKc7pw' http://localhost:8000/auth | jq .
{
  "user_role": 0,
  "user_id": 1,
  "user_email": "admin@example.com",
  "expiration": 1462262017,
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyRW1haWwiOiJzYW1mb25zZWNhQHV0ZXhhcy5lZHUiLCJVc2VySUQiOjEsIlVzZXJSb2xlIjowLCJleHAiOjE0NjIyNjIwMTd9.I_vuPtRe-mRTRh9-iSMNL7Ou4PJzgv1TLAlPz3oYKCbnEodYwYBjy_fiTB0mshEovksbn2f_STPZPgFjd1JASP5yR1ZQwccUujsZ3gW-tyK0K96qgP017l_rJIax2vjj3GjHgaMWrLPcEyPMFhdbrsS5GDrTadkxcTtlbBTKglemFBjjRB7p27QcPZvio3z4Bk7NsWTJGtkPid02DNN4LDiyRmyrbTPGAyhL_GZLVuLBpy2aMequ-L3kqEqjS-IkSXgPfxZ-gjX109bg2p3q_F5Y5fYU-j_DdIGGwzrWlUe6xyxkdTlitiwop3VF8kf0Eb_Z0NwPjYDRcO9OoKc7pw"
}
samdfonseca commented 8 years ago

Let me know whatever questions there are. Theres a few things I plan on changing if this gets accepted, like handing the key files in a non-path dependent way, but I figured this was good enough to get the ball rolling.

dinever commented 8 years ago

Hi @samdfonseca, thanks for the contribution!

I think this is a very good idea for handling authentication in APIs. However, I wonder if there is a way for us to get rid of the key files. What do we think about keeping the keys in database?

/cc @bentranter

samdfonseca commented 8 years ago

Hey @dinever, that's definitely possible, although I'm not sure its the best option in my opinion. Putting the keys in the db feels like its mixing deployment details into the application. What do you think about a config directory thats set by env var, that holds things like the db file, jwt keys, and config file?

dinever commented 8 years ago

@samdfonseca I agree. Using a configuration file should be a good practice. However, I think we need to make sure it isn't too complex for users to set up the application. For example, do you think if we can produce keys for users when they run the application for the first time?

dinever commented 8 years ago

@samdfonseca Just want to make this as simple as possible for users. As long as the key files don't make trouble for users then we should be good to go. You know, some of them don't know what RSA key does and may get stuck when creating them. 😸

samdfonseca commented 8 years ago

@dinever gotcha. I've got a commit that handles creating the keys on the first run that i'll have up in a bit. thanks for the quick feedback.

samdfonseca commented 8 years ago

@dinever how does that look?

bentranter commented 8 years ago

Wow @samdfonseca, I did a quick pass of this and this looks great so far! I've been out of town for a few days, but I'll give this PR an in-depth review when I get back tomorrow, and try to integrate it with my existing work.

Thanks for the contribution!

dinever commented 8 years ago

Looks great @samdfonseca! Do you think if there is anything else to work on in this PR? If not then we can merge this. Also, we need to remove the failing test before merging.

samdfonseca commented 8 years ago

@dinever @bentranter I'm working on adding some tests around this, but i think those can come in a follow up PR. I'm good to merge this if you guys are.

samdfonseca commented 8 years ago

just added handling for content-type application/json for POSTs to /auth/.

$ http -v POST localhost:8000/auth/ email=admin@example.com password=password123
POST /auth/ HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 57
Content-Type: application/json
Host: localhost:8000
User-Agent: HTTPie/0.9.3

{
    "email": "admin@example.com", 
    "password": "password123"
}

HTTP/1.1 200 OK
Content-Length: 915
Content-Type: text/plain; charset=utf-8
Date: Tue, 03 May 2016 01:59:33 GMT
Set-Cookie: sid=fea40068de37c93f563f42f9fd2564bad8291218e96774bbab0856ba53aaa33cf75214c97777b27f3df328591499b2373f317738228e90aac2922913574a22c2; Path=/; Expires=Tue, 03 May 2016 02:59:33 GMT; Max-Age=3600

{"user_role":0,"user_id":1,"user_email":"admin@example.com","expiration":1462456773,"token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyRW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSIsIlVzZXJJRCI6MSwiVXNlclJvbGUiOjAsImV4cCI6MTQ2MjQ1Njc3M30.EFpa6LmPv6cB0OZ2z5mxaPolqwHYxlTiFKgx-5NpKkC0WAeKUBhcjWRt7382lq2NZy4QgOnmx0da4T3hivMWyIpxmNhkOiRR6wynWzBOKrTa49SLFVWtTs1fYJGz967VoDru60JH8u6LGwJ46nXlYz5cw904LEYjJtpuszvu9fQFBI-6ZQ1hHh0QWTfxPBIfMNQ75oR80zyut04mef2TnHY58vqh5WHXNEZLjryKVUHI_IkQFfhN8afZlnvJvPVAnMeaAmfpJQbiIUZVah401RT-Niw8jfIlsj8XWt7sQG3mr9DAGqwarDAOw9eRH_BSvmutxgecZhpQWD9a2FKnSJjtJZ7WoVOuE1-YYoMhtYIm5uOjGoO8nlVUEprqA9uq8Nkx3e55o6Wdu1wM9u_--2OmnpmpKhXtYnFvlFWUbxVSfQBIxMCz8WST9IyCJuXWXlB-8rDWBjrDWQ1hGnC_ebcYEX3JPKErZ6vcCj_ygUs37_wIrOO29t23B_UDKvYggB0O8ZY1K--WStzq-483hQCp5mGPaMN-2AfNs5UqclH2BiEQ55BNNXHQ3sLgE1of4PKuhBJta3obnsM7xO7iBYpS3QT9dCXsmtvk9JPQL--zjJq07zRnuq226ln4heRk2LdMbJcIoT7BrE86mbR9jtSLzGnhjcBntIP-PONbPjs"}

$ http --form -v POST localhost:8000/auth/ email=admin@example.com password=password123
POST /auth/ HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 46
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost:8000
User-Agent: HTTPie/0.9.3

email=admin%40example.com&password=password123

HTTP/1.1 200 OK
Content-Length: 915
Content-Type: text/plain; charset=utf-8
Date: Tue, 03 May 2016 01:57:50 GMT
Set-Cookie: sid=836e00a26663df4d0fa1ae49f99d23923aa26141d959f3fc201fd66ec6c1d099c6d9e769ce8a820bb37309552c4d5645c602741fa63468fa272801815d74035a; Path=/; Expires=Tue, 03 May 2016 02:57:50 GMT; Max-Age=3600

{"user_role":0,"user_id":1,"user_email":"admin@example.com","expiration":1462456670,"token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyRW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSIsIlVzZXJJRCI6MSwiVXNlclJvbGUiOjAsImV4cCI6MTQ2MjQ1NjY3MH0.Pj1V81gqr2QaFLcoTvg_aZxnQ0HZxo3Dfrqogxj-hpOhfoL736tDCt2Fdgc4bBb7yvWQPErS58XDHfUX5XZgj-hu6F8fd8JiwD-7vhNzW76i7FrZwH28A_nKD7mpaDoKAh1AqYISfInwOi5w6lWR7OeVNJDcLPyaPP0J1uYyjTeToebPVKy8YcuEII7hIoxAu5egVcwdkc_UGJm-bZAP_bxTeeXzS5r8jDYK3YKlohG0lQLbnQQ54NqdX4ISMBT0CjjZWt7O1P-kc4MiSnJja2HAeuMg9P09nGBCbviy41DWmUsDCwhpPefJJtfMCar33mGlJee8lUifAS8thwgkZ5Jeh5xodoUyzANEQIg4DvT_GrzanPIcRxjv19t4Ea1rxrdm9lB8WsiJi2VfpYgI0IufMsktDVLUW29AaieBnV7kB2R1ABA9Js38Yj2qB4KJbjslXT3gRYkxMGtxRg29kOu-vgRAAggaQ2z16Uj6aNUK1IEr49but_3aouvV9bKSlkYYcyc72aHbZYgE9npOpXJvc1DFUdPd3WTtB-TQk51t7o-VaddU_rIcDC-N-pdv6Xn6eYOgBTh4aM17TklmxnhSg2S1RoL-NabOF8SGiYpd36kROMU17_GaiwLG4Ej753F_AidieaDZQKxFGi97axoNgjSg6gwI8mr3HZa8axc"}
dinever commented 8 years ago

Looks good. Thanks for the contribution @samdfonseca!