reset password 的網址常常是
https://yourdomain/password/reset?token=xxxx
但這樣就會被第三方網站從 `HTTP Referer` 內找到並紀錄起來 reset password 的 token,例如 google analytics,就有安全疑慮
幾個做法:
1. 一進到這個頁面馬上 invalidate 這個 token 然後generate 一個新的塞到 form 裡面
2. 進到 passwords#edit 時就把 params 移除存到 session 裡面再 redirect 回 passwords#edit 頁面,這樣 referer 就沒有token 資訊
https://robots.thoughtbot.com/is-your-site-leaking-password-reset-links
2018年7月2日 星期一
2018年6月20日 星期三
關於 API 設計的一些想法
大哉問:什麼樣的 API 是好的 API?
答案:沒有所謂的好跟壞,只有適合哪個場景。
所以要做出一個好的 API,最重要的是了解你的 API User 要拿這個 API 來做什麼。
業界常用的 Best Practice
## RESTful
常見的 API 規範:
RESTful, gRPC, GraphQL
以最常見的 RESTful (Representational State Transfer)為例說明
什麼是 RESTful? 網路上一堆複雜的說法,對我來說就是:
## Authorization
* HTTP Authentication: Basic and Digest Access Authentication https://tools.ietf.org/html/rfc2617
```
Authorization: Basic xxxxxxx
```
* JWT token - https://jwt.io/
* OAuth(2)
我們? HTTP Auth + 自製 Token
## Response
* JSON format
* Error code, error message
* 正確的 status code
## Documentation
* API blueprint
* Swagger
我們:V0,V1: Test generated HTML document, can support Swagger or API blueprint. V2: Swagger
開發流程
1. 跟 Client 討論需要的數據
2. 用 Swagger 或是 API blueprint 先寫 document
3. Client 按照 document 先 mock 資料
4. Server 開發 API, 用自動化工具測試 API endpoint 是否符合 document (Bonus: easy to TDD)
5. Client & Server 一起完工,皆大歡喜
開發盲點
1. RESTful 代表我要把 Table 映射到 API response 嗎?
2. Client 要求跟 Server 的衝突,Client 想要一個request 拿到所有資訊,Server 想根據規定給 response, 例如 GET /user 還要順便拿 user.groups 的資訊
https://github.com/shieldfy/API-Security-Checklist
- 有明確的錯誤訊息
- 回傳有意義的 HTTP status code
- 能回傳指定的格式 (Multiple Output Formats)(accept: json/application)
- 好記的名字
- Deep Filtering (order, joins, pagination)
- Typed Values - response 有固定格式
- 好懂的文件 (Interactive Documentation better)
- 能夠有版本管理,有 deprecated warning
- High Performance
- High Availability
- Developer Community
- 規範有跡可循並且一致
- Sandbox mode
答案:沒有所謂的好跟壞,只有適合哪個場景。
所以要做出一個好的 API,最重要的是了解你的 API User 要拿這個 API 來做什麼。
業界常用的 Best Practice
## RESTful
常見的 API 規範:
RESTful, gRPC, GraphQL
以最常見的 RESTful (Representational State Transfer)為例說明
什麼是 RESTful? 網路上一堆複雜的說法,對我來說就是:
- 對應正確的 HTTP Request, 新增用 Post, 刪除用 Delete, 更新用 Patch, 查詢用 Get
- 每個 EndPoint 就是一個 Resource,`GET /user` 就應該回傳 User
## Authorization
* HTTP Authentication: Basic and Digest Access Authentication https://tools.ietf.org/html/rfc2617
```
Authorization: Basic xxxxxxx
```
* JWT token - https://jwt.io/
* OAuth(2)
我們? HTTP Auth + 自製 Token
## Response
* JSON format
* Error code, error message
* 正確的 status code
## Documentation
* API blueprint
* Swagger
我們:V0,V1: Test generated HTML document, can support Swagger or API blueprint. V2: Swagger
開發流程
1. 跟 Client 討論需要的數據
2. 用 Swagger 或是 API blueprint 先寫 document
3. Client 按照 document 先 mock 資料
4. Server 開發 API, 用自動化工具測試 API endpoint 是否符合 document (Bonus: easy to TDD)
5. Client & Server 一起完工,皆大歡喜
開發盲點
1. RESTful 代表我要把 Table 映射到 API response 嗎?
2. Client 要求跟 Server 的衝突,Client 想要一個request 拿到所有資訊,Server 想根據規定給 response, 例如 GET /user 還要順便拿 user.groups 的資訊
https://github.com/shieldfy/API-Security-Checklist
2018年5月29日 星期二
ssl-cookie-without-secure-flag-set
HTTPOnly flag
https://portswigger.net/kb/issues/00500200_ssl-cookie-without-secure-flag-set
https://stackoverflow.com/questions/3773605/how-can-i-make-cookies-secure-https-only-by-default-in-rails
2018年5月25日 星期五
各種 performance 相關的技巧 - rails related and general
https://www.monterail.com/blog/actionable-tips-to-improve-web-performance-with-rails
2018年5月22日 星期二
explain https again
CA 憑證方發憑證,所謂的憑證就是包含
1. 公鑰
2. 用 CA 方的私鑰加密過的 Hash
## 具體步驟是:
- client端發起Https request
- Server端返回CA發的憑證
- Client端收到憑證,並驗證憑證是否可信,如果可信(或是使用者選擇相信)則隨機產生一段對稱式加密用的key(稱之為Key S好了),並且用憑證內的公鑰加密Key S,送給Server
- Server收到加密過的Key S,用自己的私鑰解密,並且回給Client一個ready的訊息
- Client開始和Server用Key S做對稱式加密通訊
https://medium.com/@kingapol/3%E5%88%86%E9%90%98%E5%85%A7%E4%BA%86%E8%A7%A3https-595b7d29c16
2018年5月21日 星期一
deploy vue to github page
兩個不錯的方式:
1. 用 push-dir + webpack 做
https://medium.com/@codetheorist/vue-up-your-github-pages-the-right-way-955486220418
2. 用直接寫好的 plugin
https://github.com/KieferSivitz/vue-gh-pages
目前是用後者
vue-cli v3.0.0.beta10 + vue-gh-pages v1.0.1
是很方便但是問題是
1. 必須用 /docs folder 當 gh-pages 的 root
2. 如果沒有綁 domain 的話會讀不到 js, css files,因為會連到 username.github.io/js/xxx.js 而不是 username.github.io/project_name/js/xxx.js,但後者才是正確的連結
3. docs/ folder 會一直搞爛 git 很煩
更新:找到用 vue-gh-pages 但不使用 master docs/ folder 的方法了,把 deploy script 改成下面這樣就行了:
"deploy": "node ./node_modules/vue-gh-pages/index.js -b gh-pages -o ./"
目前是就乾脆買個 domain,但比較 prefer push-dir + webpack 就是了,只是比較麻煩懶得嘗試。
1. 用 push-dir + webpack 做
https://medium.com/@codetheorist/vue-up-your-github-pages-the-right-way-955486220418
2. 用直接寫好的 plugin
https://github.com/KieferSivitz/vue-gh-pages
目前是用後者
vue-cli v3.0.0.beta10 + vue-gh-pages v1.0.1
是很方便但是問題是
1. 必須用 /docs folder 當 gh-pages 的 root
2. 如果沒有綁 domain 的話會讀不到 js, css files,因為會連到 username.github.io/js/xxx.js 而不是 username.github.io/project_name/js/xxx.js,但後者才是正確的連結
3. docs/ folder 會一直搞爛 git 很煩
更新:找到用 vue-gh-pages 但不使用 master docs/ folder 的方法了,把 deploy script 改成下面這樣就行了:
"deploy": "node ./node_modules/vue-gh-pages/index.js -b gh-pages -o ./"
目前是就乾脆買個 domain,但比較 prefer push-dir + webpack 就是了,只是比較麻煩懶得嘗試。
標籤:
Deployment,
JavaScript,
Web
2018年5月18日 星期五
2017年12月15日 星期五
bootstrap include grid
有時候會想要做到 include column 到自定義的 css class 裡面,可以這樣做:
```
@import "bootstrap";
.app {
@include make-row();
div {
border: solid 1px;
}
}
.main {
@include make-lg-column(8);
div {
border: solid 1px;
}
}
.sidebar {
@include make-lg-column(4);
}
.market {
.market-title {
@include make-lg-column(8);
}
.market-ticker {
@include make-lg-column(4);
}
}
```
```
@import "bootstrap";
.app {
@include make-row();
div {
border: solid 1px;
}
}
.main {
@include make-lg-column(8);
div {
border: solid 1px;
}
}
.sidebar {
@include make-lg-column(4);
}
.market {
.market-title {
@include make-lg-column(8);
}
.market-ticker {
@include make-lg-column(4);
}
}
```
2017年12月7日 星期四
網路安全相關 - JWT
JSON Web Token
https://jwt.io/
現在很流行用 JWT 當作 HTTP basic auth 的 token
通常會長這樣
```
header["Authorization"] = "Bearer <YOUR_JWT>"
```
什麼是 HTTP basic auth? 參考 這篇文章
為什麼呢? 要先簡單介紹 JWT 才能回答這個問題
JWT 其實就是一個協定告訴你怎麼產生 token
要產生 JWT 的 token 必須包含三個部分
1. header
2. payload
3. signature
header 裡面描述了想要加密用的演算法,用來產生 signature
payload 就是一些想要讓 client 可以解析的數據
signature 就是把 header 和 payload 用 server side 才知道的 secret key 加密產生出的一串字串,用來驗證資料正確性。 可以參考 摘要算法和對稱加密算法
把 header+payload+signature 分別用 Bas64 encode 之後就變成了 JWT token
格式長這樣
encoded_header.encoded_payload.encoded_signature
那回到一開始的問題,為什麼要用 JWT 呢?
主要原因就在於這個 token 是自帶資訊的,因為我們把 加密方式、想要傳達的訊息 都存在 token 裡面了,而且還加上了 簽名 用來確保訊息的正確性。
來看看實際面吧,假設我有個前端頁面想要跟 sever 溝通,以前的作法前端跟 server 拿 token 的時候, server 亂數產生一個 uniq 的 token 給前端,之後的每個 request 就帶這個 token 作為驗證的方式
流程一樣,但我們把「server 亂數產生一個 uniq 的 token 給前端」這件事改成「server 產生一個 JWT token 給前端」會發生什麼事(以及應該怎麼做)呢?
首先定義我的 paylaod
```json
{
user_id: 1,
name: "Wayne",
permissions: [
"read_account", "write_account"
]
expired_at: 1512624558 // unix time,
token: "my-uniq-token-from-server"
}
```
然後加密成 JWT token,把這個 token 傳給前端
有什麼好處呢?
1. 前端可以用 Base64 decode payload,這樣前端就可以直接從 token 就知道我提供給他的各種資訊,例如此例前端就可以知道這個 token 有哪些權限、什麼時候過期等等
2. Server 在收到帶有這個 token 的 request 的時候,也可以從 payload 直接判斷 token 過期了沒、有沒有操作權限
3. Server 不用擔心 payload 是不是被改動過,因為只要把 payload decode 出來並用依樣的加密方式加密比對 sinature 是否一樣就知道 paylaod 是否正確
https://jwt.io/
現在很流行用 JWT 當作 HTTP basic auth 的 token
通常會長這樣
```
header["Authorization"] = "Bearer <YOUR_JWT>"
```
什麼是 HTTP basic auth? 參考 這篇文章
為什麼呢? 要先簡單介紹 JWT 才能回答這個問題
JWT 其實就是一個協定告訴你怎麼產生 token
要產生 JWT 的 token 必須包含三個部分
1. header
2. payload
3. signature
header 裡面描述了想要加密用的演算法,用來產生 signature
payload 就是一些想要讓 client 可以解析的數據
signature 就是把 header 和 payload 用 server side 才知道的 secret key 加密產生出的一串字串,用來驗證資料正確性。 可以參考 摘要算法和對稱加密算法
把 header+payload+signature 分別用 Bas64 encode 之後就變成了 JWT token
格式長這樣
encoded_header.encoded_payload.encoded_signature
那回到一開始的問題,為什麼要用 JWT 呢?
主要原因就在於這個 token 是自帶資訊的,因為我們把 加密方式、想要傳達的訊息 都存在 token 裡面了,而且還加上了 簽名 用來確保訊息的正確性。
來看看實際面吧,假設我有個前端頁面想要跟 sever 溝通,以前的作法前端跟 server 拿 token 的時候, server 亂數產生一個 uniq 的 token 給前端,之後的每個 request 就帶這個 token 作為驗證的方式
流程一樣,但我們把「server 亂數產生一個 uniq 的 token 給前端」這件事改成「server 產生一個 JWT token 給前端」會發生什麼事(以及應該怎麼做)呢?
首先定義我的 paylaod
```json
{
user_id: 1,
name: "Wayne",
permissions: [
"read_account", "write_account"
]
expired_at: 1512624558 // unix time,
token: "my-uniq-token-from-server"
}
```
然後加密成 JWT token,把這個 token 傳給前端
有什麼好處呢?
1. 前端可以用 Base64 decode payload,這樣前端就可以直接從 token 就知道我提供給他的各種資訊,例如此例前端就可以知道這個 token 有哪些權限、什麼時候過期等等
2. Server 在收到帶有這個 token 的 request 的時候,也可以從 payload 直接判斷 token 過期了沒、有沒有操作權限
3. Server 不用擔心 payload 是不是被改動過,因為只要把 payload decode 出來並用依樣的加密方式加密比對 sinature 是否一樣就知道 paylaod 是否正確
2017年10月22日 星期日
整理 SASS 的方法
教了很多整理 SASS 的方法,主要是用 mixins
https://www.toptal.com/css/sass-mixins-keep-your-stylesheets-dry
偷懶也可以直接使用 Sass mixin libraries,例如文中提到的 bourbon 和 andy
http://bourbon.io/
http://gillesbertaux.com/andy/
https://www.toptal.com/css/sass-mixins-keep-your-stylesheets-dry
偷懶也可以直接使用 Sass mixin libraries,例如文中提到的 bourbon 和 andy
http://bourbon.io/
http://gillesbertaux.com/andy/
SASS 做 theme 的起手式
不錯的文章
* 最外層的 container 控制 theme 基本元素
* 加上 themable 的 mixin 並設參數讓 theme 更彈性
* 用 each 方法 loop 參數,讓 themable 更彈性,只需要接受 name 和 map 兩個參數
* lighten & darken 方法做到 hover 效果
https://www.toptal.com/sass/theming-scss-tutorial
* 最外層的 container 控制 theme 基本元素
* 加上 themable 的 mixin 並設參數讓 theme 更彈性
* 用 each 方法 loop 參數,讓 themable 更彈性,只需要接受 name 和 map 兩個參數
* lighten & darken 方法做到 hover 效果
https://www.toptal.com/sass/theming-scss-tutorial
2017年10月10日 星期二
reddit 上的 rails performance 總結
The Complete Guide to Rails Performance 這本書 https://www.railsspeed.com/ 的總結:
https://www.reddit.com/r/rails/comments/5x0wd2/has_anybody_purchased_the_complete_guide_to_rails/
- Measure. If you have a serious project a cost of NewRelic account is negligible but insights it provides are very valuable. Make sure you measure request queue time, when you have large variance in request processing time (some are slow, some are fast) you may want to switch from Nginx to Haproxy as a front-end.
- Cache output. With large JSON/HTML responses you'll move from 300ms to sub-10ms. Use Russian doll caching
- Use conditional GET
- Use proper DB indexes. If they aren't enough, denormalize in RDBMS or use Shopify's
identity_cache. There are gems that suggest what indexes you are missing. Remember that indexes are useful when searching using a prefix of indexed columns, so if you have an index on(name, created_at)it will be used when searching or sorting byname. Read "Use the index Luke" it contains pretty much everything you need to know about them. - If you are managing a database yourself and it's PostgreSQL, read the configuration chapter in the docs and change the settings accordingly. Defaults aren't optimized for performance.
- DB optimization is a huge topic. If some query is unusually slow, make sure execution plan is correct. PostgreSQL optimizer sometimes messes up and uses hash join-table scan instead of nested loop. Increase stats granularity or force it to use nested loop. Read http://a.co/2GF5Sg8 if you want to know more.
- Avoid N+1, make sure to include related records in queries. In rare cases it's better to use N+1 with Russian doll caching but generally avoiding N+1 is better. There are gems to detect N+1.
- Play with number of processes and threads per process in your app server. Multi-threading helps with I/O bound tasks (querying a slow database, calling remote servers).
- Enable out-of-bound GC in your app server, so that GC won't happen during requests. It has minimal impact but still.
- Off-load long-running tasks (e.g. resizing images and calling external services) to background workers. Use Sidekiq, it's amazing.
- Don't bother with EventMachine, it sucks.
- Make a choice on what to do with JS files. Either use CDN to serve third-party libraries individually or bundle them in a separate file.
- Serve static assets from CDN.
https://www.reddit.com/r/rails/comments/5x0wd2/has_anybody_purchased_the_complete_guide_to_rails/
2017年9月1日 星期五
2017年8月13日 星期日
CSS Grid
推薦連結:
https://www.youtube.com/watch?v=txZq7Laz7_4&feature=share
TL;DR:
CSS grid 先把畫面切隔成不同的區塊後再把 content 丟到區塊裡,符合設計直覺
只套用第一層子元素
做 RWD 很方便,且省略了很多不必要的 nested elements
挺酷的
https://www.youtube.com/watch?v=txZq7Laz7_4&feature=share
TL;DR:
CSS grid 先把畫面切隔成不同的區塊後再把 content 丟到區塊裡,符合設計直覺
只套用第一層子元素
做 RWD 很方便,且省略了很多不必要的 nested elements
挺酷的
訂閱:
文章 (Atom)