CSS

Can I use? 線上快查HTML5/CSS3屬性的瀏覽器支援度
https://caniuse.com/

成為 CSS 團隊的一員:CSS 團隊開發的最佳實踐
本文分享了 如何最佳化管理與維護日益增加的 CSS 文件內容 
無論是對個人還是團隊來說,這點很重要!!!
原文:https://msdn.microsoft.com/en-us/magazine/ff679957.aspx
中文翻譯:http://msdn.microsoft.com/zh-tw/magazine/ff679957.aspx

CSS 版面配置
http://zh-tw.learnlayout.com
https://www.slideshare.net/jaceju/css-1104887

網頁排版 (單欄式、二欄式、三欄式)
http://www.wibibi.com/info.php?tid=405
http://www.wibibi.com/info.php?tid=406
http://www.wibibi.com/info.php?tid=407

CSS 排版兩大利器:Flexbox vs Grid
https://21st.each1.net/2018/11/css-flexbox-vs-grid.html

好用的 css 3新單位 vh vw ─ 讓你的圖片可以隨著螢幕大小而不同
https://pjchender.blogspot.com/2015/04/css-3vh-vw.html

用 CSS的 table屬性取代 古早的 table排版
https://www.minwt.com/webdesign-dev/css/6694.html

float 浮動元素 (比如說 文字繞著浮動的圖片 等應用)
http://www.wibibi.com/info.php?tid=167

常見的 30 種 CSS 選擇器
https://code.tutsplus.com/zh-hant/tutorials/the-30-css-selectors-you-must-memorize--net-16048

選擇器中的大於(>)
https://pjchender.blogspot.com/2015/07/css.html

多重選擇器 (包含空白或逗號)
https://pjchender.blogspot.com/2015/03/cssmultiple-selectorsspace.html

CSS 偽元素 ( before 與 after )
http://www.oxxostudio.tw/articles/201706/pseudo-element-1.html

CSS3 :nth-child(n) 選取器教學
http://csscoke.com/2013/09/21/%E4%BD%BF%E7%94%A8css3-nth-childn-%E9%81%B8%E5%8F%96%E5%99%A8%E8%A9%B3%E8%A7%A3/

How TO - Toggle Switch 開關切換
https://www.w3schools.com/howto/howto_css_switch.asp
https://www.w3schools.com/howto/howto_js_display_checkbox_text.asp


https://dotblogs.com.tw/knightzone/2013/09/07/116716

使用@keyframes建立動畫內容
animation: name duration timing-function delay iteration-count direction;
animation-name: 動畫名稱;
animation-duration: 動畫作用時間;
animation-timing-function: 動畫補間時運用的計算公式;
animation-delay: 動畫需間隔多久後才開始;
animation-iteration-count: 動畫作用次數;
animation-direction: 動畫作用的方向;

timing-function有linear、ease、ease-in、ease-out、ease-in-out可以用,或者可用cubic-bezier(n,n,n,n)來自己制定(0 <= n <= 1)。

至於iteration-count如果要無限多次可用infinite。

最後動畫作用的方向指的是動作作用的時候可以是@keyframes相反的方向(to->from、100%->0%)(reverse),或是作用完後又回頭(alternate)、或是先相反再變正常順序(alternate-reverse)。





HTML

W3C HTML5 – header、footer、main、address:
http://blog.shaochuancs.com/w3c-html5-header-footer-main-address/
https://www.w3.org/TR/html5/sections.html#the-header-element

HTML5 中的 data-* attribute 屬性
https://pjchender.blogspot.com/2017/01/html-5-data-attribute.html



HTML 5  規範的語意化標籤

<header>
顧名思義就是頭部,主要是用來放置網站的刊頭,固定會重覆出現的導覽、LOGO、站名等內容。

<footer>
尾部,包括頁尾,像是法律資訊或是作者訊息等等,不過<header>及<footer>都不是唯一的,在網頁中的同一個區域可以重覆使用。

<nav>
導覽列,像是選單之類用來導引使用到網站各個地方的,可以用<nav> 包起來,在裝置上的操作是可以直接跳過、跳是跳到這個段落然後跳選下一個連結。

<main>
HTML <main>元素呈現了文檔<body>或應用的主體部分。主體部分由與文檔直接相關,或者擴展於文檔的中心主題、應用的主要功能部分的內容組成。這部分內容在文檔中應當是獨一無二的,不包含任何在一系列文檔中重複的內容,比如側邊欄,導航欄鏈接,版權信息,網站logo,搜索框(除非搜索框作為文檔的主要功能) 。
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/main

<aside>
側欄,網頁中非主要區域的地方,常見放廣告及導覽、全站檢索的地方。

<article>
文章,意指一篇完整而可獨立抽出來閱讀的文章。

<section>
章節,表示相關但是不同的段落,段落tag裡也可以包<article>, <article>裡也可以包<section>主要的差別是語意上的。


<header>:網頁的標頭,通常放置網站標題。
<nav>:網頁的選單、導覽。
<main>:網頁的主要內容。
<aside>:網頁的側欄、附加內容。
<article>:一篇文章內容。
<section>:自訂的區塊,例如數篇摘要組成的空間。
<footer>:網頁的頁尾,通常放置聯絡方式、著作權宣告等等。
<mark>:Highlight parts of a text.
<time>:顯示日期時間。


Google 的 Matt Cutts 說過的話、發表的內容可以相信,因為他是搜尋引擎的頭頭,基本上 SEO 的規則他說了算。不過要得到彙整過、消化過的資訊並不容易,因為他發布的消息比較零散。

這篇「How To Use H1-H6 HTML Elements Properly」根據 Matt Cutts 做了一些整理,也是本文內容的依據:

H1、H2 等標籤不必依照順序,搜尋引擎仍可處理(依據影片內容)

一個頁面最好只使用一個 H1 → 雖然根據影片,Matt Cutts 說不要到處都是 H1 就好,但一個頁面使用一個 H1 "才是這個標籤的本質"。相信當一個頁面只要不是刻意使用超過一個 H1,Google 有辦法判斷出該使用方式是否為惡意、還是正常使用。

H2 最好使用二~三個就好 → 避免分散權重

H3 最好使用二~三個就好 → 避免分散權重

H4~H6 不太重要

For example, this is semantically correct:
<h1>Website Design Basics<h1>
<p>Here is some text</p>
<h2>HTML</h2>
<p>Here is some text</p>
<h2>CSS</h2>
<p>Here is some text</p>



何謂OEM、ODM、OBM、IDM

OEM

Original Equipment Manufacturer最初被稱為原始設備製造,現在則被稱為「專業(委託)代工」。

主要是純代工,不含產品設計,設計及配方是由委託廠所提供的,賺的是勞力工錢。

製造商依企業客戶需求,生產符合客戶要求的產品,後掛上企業客戶的商標品牌,由客戶自行銷售。因此,接獲訂單的製造商,所製造出的相似商品,會掛上許多不同的品牌。會下OEM單的企業,是基於節省生產成本和部份管銷費用的成本考量

需具備充裕的勞動力,提供國際市場上所需的產品製造、組裝之委託代工服務能力。

 ODM

Original Design Manufactures「原廠委託設計」
除代工生產外,產品的配方及設計是屬於代工廠的,這可提高代工價格,並守住客戶不流失,除非客戶用另一設計,所以客戶擁有品牌權。

需具備產品設計開發及生產組裝能力,並能與ODM買主共同議定產品規格,進行產品設計或改良的工作。

OBM

Original Brand Manufacture「建立品牌」自有品牌及生產,跳脫代工範疇,是品牌擁有者。需需具備行銷通路能力來推銷販賣產品,發展出自己的企業形象,進而獲取最大的經濟利益。

IDM

Integrated Devicd Manufacturer「整合元件製造」

指從設計、製造、封裝測試到銷售自有品牌IC都一手包辦的半導體垂直整合型公司。

需具備高技術與資本密集之特性與能力,依其技術與資金上的優勢席捲市場,形成少數獨大的寡占局面。

在產品設計與發展的活動,經由高效能的產品開發速度與具競爭力的製造效能,滿足買主需求。足夠的技術能力及不斷的提昇設計能力,進而能夠開始接案接單並處理產品的相關設計開發。


『適合創業』的台灣人,我們可以再勇敢一點」:夫妻拋下「鐵飯碗」,來到英倫「白手起家」

來源:https://crossing.cw.com.tw/blogTopic.action?id=717&nid=10307

作者前言:旅居國外,最常見的理由,不外乎遊學、留學、工作、打工度假、移民等,但你是否曾想過「創業」這個選項?本文訪問了原本在台灣捧著鐵飯碗的夫妻檔──Ines 和 Aquila,分享在英國創業的心路歷程。

根據英國官方統計,今年通過的投資移民/企業家簽證(Tier 1),比上個年度增加了 11%,顯示在現今脫毆局勢不明的狀況下,工作簽證(Tier 2)的簽核日益嚴謹,卻有更多 Tier 1 簽證被核發通過,是所有簽證類型中,增加幅度最大的。

英國創業不是這麼遙不可及的事,在學校、工作場合中,時不時能聽到身邊的人正規劃要創業,或是「創業進行式」。創業是一種很普遍的風氣。相較於台灣,英國的創業內容十分廣泛,只要你有特別的點子或別人需要的專業,一個房間、一台電腦就能開一家公司──成功了,恭喜你!失敗了,成為你履歷的一部份,也很好!

從興趣中發現商機

原本在台灣從事教育工作的 Ines 和 Aquila 夫妻檔,都是熱愛自助旅行的背包客,至今闖蕩了 60 多個國家,對於民宿、旅程規劃已擁有深厚經驗。

因為在歐洲唸書時受到環境的鼓舞,一開始用自雇的方式分租家中空房,慢慢地看到台灣人在倫敦旅遊、求學、找房、移民等商機;終於決定於 2016 年創業,主攻以民宿為主的物業管理、移民/教育/置產顧問,旗下的民宿至今拓展到四、五館,皆位於倫敦市中心的精華地帶,在台灣人的圈子裡小有名氣。

台英消費心態的差異與挑戰

台灣以製造業起家,習慣有「實質物品」的交易,諮詢顧問是一種「殺必俗」,不過幾句話而已,憑什麼要收錢呢?而英國是個注重服務專業的國家,因此產生各種顧問代辦公司,收費也常是以小時計算,這點和台灣視「服務顧問業」為低生產低貢獻的心態大異其趣。

也因此,Ines 和 Aquila 作為「台灣客人」和「英國合作商」的橋樑,需要很多智慧和心力:台灣客人喜歡俗又大碗,要求免費或價廉的服務,而英國人對於每一個意見跟詢問是按時收費的,在兩者之間周旋是非常燒心燒腦的事情。尤其兩邊的溝通和做事方法差異頗大,往返的信件、電話中,常耗費不少成本。偶爾遇到頤指氣使,認為每種服務都是理所當然的家鄉顧客,更有不為人知的心酸。

在英國創業的條件

當然談到創業,還是有些必要條件。在英國創業的首要困難,當屬「簽證(Tier 1 Entrepreneur Visa)」。除了至少 20 萬英鎊(約 800 萬台幣)的投資基金外,更有許多法規和條款等限制,一開始得做足功課避免踩到地雷。

再來,語言能力不可或缺,大多數的創業需要許多溝通跟支援,結交各地朋友、研讀當地相關資料,英文的基礎一定得有。最後也是最基本,擁有獨到的點子或專業,才是決定你的創業能否在市場存活的關鍵因素。

談到為何在倫敦創業,夫妻倆笑稱:「就是一股傻勁」,Ines 唸博士班時訪問許多小型的創業公司。相較台灣,這裡的風氣鼓勵創業,只要你有好的想法,身邊的人幾乎都十分支持。英國的商業發展蓬勃,機會跟可能性也多,看似小眾的市場也能接觸到很多大眾。

台灣人,我們可以再勇敢一點

以往在台灣捧著鐵飯碗的兩位,曾覺得人生只要有個穩定職業就好,但來到英國唸書後,個人價值觀卻受到許多衝擊。其後,因經營民宿接待了上千組客人,有機會觸碰各式各樣的行業,和各種精彩有趣的人生,思考範圍越來越寬廣。

台灣人的努力跟專業其實非常適合創業,只是我們通常卡在第一步就打退堂鼓。對於未知的恐懼,讓我們在還未起步前,就想著失敗的未來,不傾向承擔風險。

Ines 分享:「在這裡做專業服務其實很難失敗,以台灣人的性格慢慢的經營,頂多沒錢做,但不至於一敗塗地。」如果擁有專門的技術或服務,再配合當地的設計跟包裝,就有機會成功。

承擔風險,跨出精彩人生的第一步

臉書創辦人祖克柏曾說:「最大的風險不在於承擔風險⋯⋯在一個快速變動的世界,唯一保證會失敗的策略,就是不承擔風險。」(The biggest risk is not taking any risk⋯⋯ In a world that changing really quickly, the only strategy that is guaranteed to fail is not taking risks.)

在倫敦,筆者的一個體悟是,當我們真心想做一件事情時,就勇敢去做。創業只是其中一個例子,人生是結合各種經驗的旅程,即使是負面的經歷,也能從中學到許多知識跟智慧。那些內心的害怕、外在的雜音,其實都不那麼重要,我們該專注的是如何努力爭取、想方法、找資源,會比猶豫躊躇原地好很多。

精彩人生值得我們往前一步、扛起更大的風險!


技術選型

新技術不斷地冒出,這意味著機會並伴隨著風險,如何評估是否採用呢?

Hype Driven Development: https://blog.daftcode.pl/hype-driven-development-3469fc2e9b22

Good practices

So if we can’t rely on what the internet says and opinions of other people, then how to make clever decisions? Here come some good practises:

Test and research before you decide:

Spikes — learn about your technology not from blogs, but from experience. Take 1 or 2 days to build a prototype of a new functionality in the new technology, before you make the decision. Let the team analyse pros and cons. You might take a couple of competitive technologies and let different parts of the team builds prototypes with different technology.

Hackathon is a great way to build awareness of a team on tradeoffs of different technologies. Take 1 or 2 days for the whole team to hack all the technologies that are on the rise and look tempting to use. That will allow the team to make clever decisions on its own and take decisions based on their own experience.

When to go?

In principle when the return on investment is huge. Most technologies are created to solve a particular problem. Do you have that problem? Is it a big problem? Will it save a lot of time? Will the use of the technology pay back the cost of the entrance curve and rewriting? What if we initially slow down development by the factor of two? Or four? Is it still worth it?

Great teams are allowed more — some teams are just faster than others at delivering the value. They get bored with what they do more easily. These teams can introduce new technologies more often. That’s no excuse not to use spikes and do hackathons. On the other hand, if the team has troubles delivering — proceed with caution.

Hire the right people:

Strong technical background is your friend — people who know different paradigms, understand the theory of programming (e.g. algorithms, concurrency) and have good engineering culture tend to hype less.

Experience — hype is stronger with young developers. With years people who have seen many technologies and been in troubles many times tend to get more balanced views of picking technology.

Big Data 的 8 個迷思

資料分析學(data analytics)和「大數據」(Big Data)給予了人們徹底顛覆「行銷」的期盼。

大多數公司都從許多管道蒐集到大量的數據:包括:財務數據、行動數據、交易數據、顧客研究數據、行為數據、社群媒體數據等等。在新的分析技術、電腦運算能力倍增,以及線上資源即刻可得的推波助瀾下,更是催生出許多功能強大的工具,帶來了永久性的改變。

這些分析工具及技術的力量之大,已經使得分析學的應用範圍大大地延伸,不僅有助於開啟新的機會和策略,也開創了過往從來無法想像的可能性。

不過,分析「大數據」這件事,卻被講得太過簡單了。實際上,運用大數據還是一項亂無章法、非常勞力密集的工作。

借用兩個真正在做這項工作的人所說的話:關於大數據的部分言過其實的宣傳,給我們帶來了麻煩,因為這形成了一個錯誤的期待,彷彿大數據有多麼簡單似的。

因此,我們可以開始務實地看待大數據,是時候該終止這些經常聽到的迷思了。

積累數據前先自問:目的是什麼?

大數據迷思 1:大數據很大

大數據一點都不「大」(big),而是很多元(diverse)。 「大」頗有誤導之嫌。

我們所談論的其實是各式各樣來源的大量「數據點」(data point;一個資料集裡的一個可供辨識的要素,泛指一則資訊或一項事實),即時地、高頻率地在更新。它的性質非常細碎,可能是個人的交易數據:像是某張信用卡在某個加油站,被用來支付特定一筆油錢。

換言之,大數據實際上是巨量、海量的非常細小的數據。它不是一批有如土石流般傾瀉而下的數據;而是一場沙塵暴。在沙漠裡,陣陣強風所掀起的無數砂粒,可能會讓你眼盲、讓你失去方向感。

有鑑於此,想要在沙塵暴中看清楚,我們還需要破除哪些迷思?

大數據迷思 2:你必須立刻採用

生命中,大多數重要且有價值的事物,都是困難的,大數據的分析也不例外。想要解決這個難題,只能一小步一小步來,並且從非常清楚具體的目標著手。

在你動手囤積數據之前,請謹慎地思考你到底想要拿這些資訊做什麼?

大數據迷思 3:數據愈精細愈好

數據愈是即時、愈精細,總是愈好?不,一點也不。一場足球賽只看前四分之一,並無法預測整場比賽的結果。即時取得的資訊很可能因為為時尚早,而無法據以採取行動。有時候,你必須把時間拉長、把鏡頭拉得更遠,才能看得見全景,掌握事物的全貌。

大數據裡充斥著大量的雜訊(white noise)。隨著解析度愈高,好比說每分鐘而非每星期的數據,或是一個城鎮的規模而非一個州的數據,噪音占整體訊號的比例就會增加。

不要混淆了精準度(precision)和正確性(accuracy),兩者的差異有必要被釐清。大數據如果是在原始、四散的形式時,是有可能會誤導人心的;它需要集結到一個適當的程度,才能排除掉雜訊。

大數據迷思 4:大數據是好數據

「大量的數據」和「大量的好數據」是有差別的。

劣質數據裡有很多錯誤、很多遺漏的數據,是會造成誤解的。照片和影片可能會被標記錯誤,而青少年所寫的亂無章法的訊息,難道就足以反映出正面或負面的情緒?有時候,我們需要一個聰明的模型來釐清這一切。

為了正確解讀資料的意義,你必須丟棄某些資料。想要正確分析大數據,首要任務之一就是:你必須釐清,你打算將什麼樣的資料納入你的分析中,又必須丟棄哪些資料。

大數據迷思 5:大數據意味著「分析師」將變得異常重要

經常有人說,大數據將會帶來分析師(analyst)這項職業的興起,他們將成為「資訊時代的新寵兒」。不過,這種主張「資料分析團隊」(analytics team)即將崛起的說法,其實是被過度誇大了,因為資料增生速度的大幅提升意味著,人們現在根本就沒有時間去「向分析團隊做簡報」。

我們需要的是擁有更快速的工具,能夠因應數據新增的速度、數量和精細度。

理想狀況下,一小群專精的分析師,懂得善用科技的力量,讓企業或行銷人員能夠自行完成更多的資料分析、情境模擬和決策輔助。我們預估,資料分析部門(Analytics Department)將會消失,自助服務(self-service)將日益普及。資料科學家(Data Scientist)占據優勢地位的時代不會永久存在,因為數據實在是太多了!

大數據迷思 6:大數據能夠給你具體的答案

模稜兩可是大數據的主要特色。多重的數據來源(例如,交易、潛在顧客開發和媒體)可能會引導你偏離了證據所指的方向。不同的數據,如果未能正確地分析,確實可能會得出相互衝突的證據。你要選擇相信哪些數據?

大數據需要人去做判斷,去調停和解決看似彼此衝突的證據,而那正是技術高超的分析師可以施展長才之處。

你擁有的數據愈多,你就愈有可能遇到有待解析的矛盾和模糊。大數據沒有那麼萬能、強大;事實上恰恰相反。更多的數據可以給你更多的證據,卻不會讓你更貼近真相,除非你能夠靈活運用有經驗的人腦判斷,去調和這些相互衝突的證據。

資料分析學的未來就是:結合、權衡和判斷多重的資訊來源和不同的分析。

大數據迷思 7:大數據是一顆「神奇 8 號球」

(編按:神奇 8 號球指的是 Magic 8-Ball 這款玩具,外型就像撞球台上的 8 號球,使用者可以提出問題,搖晃球體後,會浮現出答案。可以用來占卜、尋求建議。)

嗯,這麼說也沒錯,但是你必須用非常正確的方式來問問題。這有點像是當一個精靈給了你 3 個願望,你得非常謹慎地措詞。

在應用資料分析學的時候,如果不夠精準或是事先沒有形成細緻的假設,反而會讓你誤入歧途,並且給出一個不正確的答案。手上握著「大數據」這個水晶球時,你要非常小心地發問。

大數據迷思 8:大數據可以建立自學的演算法

從行銷的觀點來看,參照「無架構、未管理的數據」(rogue data)所得出的錯誤推論,點出了自動化模型的局限:例如,從直接回應電視廣告(direct response TV ad;在廣告中直接號召觀眾撥打電話、傳真或寫信,以獲得產品樣本、目錄或直接購物)來預估客服中心的來電話量,結果勢必會產生誤差。

同理,從美式足球超級杯(Super Bowl)賽事周末所取得的「無架構數據」,也很有可能會扭曲一套自動更新的演算法。

演算法如果以正確的方式加以設定,確實可以發揮強大的功能,但是這其中總是需要人腦的介入。行動電話業者已經做出了良好的示範,將非行銷數據(non-marketing data)用於行銷用途:他們知道你的朋友有哪些人;他們可以猜測你的年紀;他們知道你出沒在城鎮的哪些地帶;他們知道你瀏覽過哪些網站;他們也知道你正在使用、還有在哪裡使用哪些 app(手機應用軟體)。

保險公司也可以使用無線遙測技術(telemetrics;針對相隔一定距離的對象進行檢測,並將結果傳送到接收地點)來取得數據,並用於行銷,而非只是承辦承銷保險。

基本上,釐清這些迷思的本意,是想排除以下的盲目信念:擁有數據,就可以確保企業成功。

真相是,大數據本質上就是一項工具,無異於電腦或智慧型手機,是一項很棒、能夠改變遊戲規則的工具,但是這項工具只有在交由懂得正確指令和座標的人使用時,才能發揮這樣的作用。

關於大數據的部分言過其實的宣傳,給我們帶來了麻煩,因為這形成了一個錯誤的期待,彷彿大數據有多麼簡單似的。

(資料來源 / ,作者 Joerg Niessing,INSEAD 行銷學合聘教授;James Walker,顧問公司 Strategy& 合夥人)

插畫接案:東方與西方的差異

下文為轉載僅作為自己私人留存,並對原文用字遣詞不甚理想之處予以潤飾,便於自己閱讀。


在插畫業界,插畫師遇到不尊重和不了解插畫產業價格的客戶,往往只能忍耐或是抱怨,尤其是東方的華人客戶,時常是插畫師們抱怨的對象。為何會被抱怨呢?首先藝術設計教育在東方基本上是失敗的 ,而東方華人對於不了解的事情總是以忽視或是瞧不起的態度來對應,認為藝術設計如變魔術般簡單,有人願意花錢就不錯了。所以導致客戶不尊重藝術設計創作者,進而在合作的過程中、態度和價格等方面產生了歧異和觀念上的偏差。現在姑且先不論東西方插畫價格的差異,我們聊聊合作上的經驗!

我最近在個人的臉書發表了一篇文章,是關於我與歐美和亞洲華人客戶合作的差異,得到了一些迴響;如華盛頓郵報的藝術總監、跨國插畫經紀公司的經紀人和國際頂尖的插畫師都深有同感並幫我按讚與留言,訴說他們也有同樣的合作經驗與感受!而之後他們就會婉拒與這些客戶合作。

雖然西方也有不了解市場價格的客戶,但是對於插畫師們還是會給予該有的尊重,然而東方卻是連大型的客戶都會在這方面表現出非常不專業的合作模式,或是自我感覺良好地以為自己的方式是正確的合作模式。


簡單地翻譯一下這個圖片:

與客戶合作:

美國或英國客戶:

跟你溝通合作的窗口往往是擁有藝術設計相關高學歷的創意總監,而且他們知道他們需要什麼!補充:他們因為知道他們需要什麼,所以找上你時就是喜歡你的風格和創作成品。

中國或台灣客戶:

很少人是藝術設計相關學位或是學歷畢業,自身也不是很了解自己要什麼樣的藝術設計。他們可能會希望你模仿另一位目前當紅的插畫師的作品或是創意風格。

草稿階段:

美國或英國客戶email回應:

太好了!我們就選擇這一個創作方向,我好期待看到完成品!

中國或台灣客戶email回應:

*我覺得這好像不是在畫那個人…(然而這只是草稿階段)

*這裡我看不懂,那裡我看不懂耶!是在畫什麼呢?(已經把桌子畫得像桌子的速寫之類)

完稿階段:

美國或英國客戶email回應:

太棒了!我們很喜歡!下次再一起合作吧!請把帳單寄來!

中國或台灣客戶email回應:

*我們可不可以加上____?

* 不然我們先把這個拿掉…好像不好耶…再放上去好了!

*不然我們換一個畫法和創意方向吧?什麼??竟然要加錢?

*我覺得這個人畫的不像。

*不然你原始檔案給我,我讓別的設計師加些東西。

*修改很簡單啊! 你趕快弄一弄給我!

*重畫一下又不難!

看完個比較,大家或許會好奇,難道是歐美客戶比較自由隨意?華人客戶比較嚴謹審慎?



其實歐美國家的客戶們,發函與你對接的商業窗口,往往是公司聘請的藝術設計總監。他們擁有藝術設計領域的高學位以及豐富的設計經驗,是代表公司藝術設計方向的權威,所以在合作時都會思考再三,並先有公司內部會議,才會決定要聘用的插畫師。歐美藝術總監們不僅了解公司該出現什麼樣的創意設計,能分辨什麼樣的作品是好作品,也知道自己和公司需要什麼,而公司也願意相信他們的專業知識。因此,鮮少出現有藝術總監通過完成的作品,呈交上層卻不通過的事件發生;既使不幸發生了,也會在創作的草稿階段就得到修正,或是在完稿階段有相對應的處理方式。所以在合作案上就不會出現外行 (沒有受過長年藝術設計教育或學位) 裝內行或是領導內行的情況,也不會有完稿階段改東改西的事情發生。

上一段提到歐美客戶的專業性,但是歐美國家並不是百分之百不會犯錯誤,偶爾也會發生突然的藝術方針的改變,而這部分也分兩個階段:草稿和完稿。需要插畫師修改創作時,如果是草稿階段沒提到的,態度會非常委婉甚至願意付修改費用,而更有水平的客戶是直接呈上修改費並對於需要修改的部分感到抱歉。 無論是大公司如 Apple Inc. 到小公司如獨立的出版社,基本上對於合作的插畫家的態度都是相當尊重而且慎重的。

然而與華人客戶合作的經驗,深深讓我感到在藝術設計合作案上的不專業,而華人插畫家們,自己也把這些廠商慣壞了! 雖然畫師與廠商解釋專業該有的合作方式可能會沒工作,但不解釋糾正又要責怪被廠商欺負。廠商可能也很無辜,因為他們可能在之前的合作案上,跟某甲某乙都可以那樣改來改去甚至低價合作,所以認為這樣的合作方式是沒有問題也是正確的,但其實卻是非常錯誤的一種方式與態度。

有些華人廠商找插畫師時,會直接說現在誰紅就找誰!這是在歐美不會發生的現象,因為藝術創意總監或是廠商是應該帶領潮流來發掘好的藝術設計作品,而不是隨波逐流。如果被潮流帶著走,而認為人氣高低代表作品水準好壞,其實也是體現了負責人不夠專業且無法分辨作品優劣。造就高人氣有許多方式,有的人是行銷包裝的模式高人一籌,有的是人脈關係的經營等等,但不一定是作品品質的保證,許多歐美真正大神的插畫師也只有兩三千個追隨者,但卻是紐約插畫師工會和國際插畫市場上的名人堂等級。

是否要挖掘好作品給大眾欣賞,來自於廠商或老闆的良心。畢竟身為廠商或是傳播媒介,你們都擁有了一個很大的權力,那就是讓大眾看到什麼樣的藝術設計作品,如果你擁有這個至高的權利卻不懂得好好把握,那就代表你只是為了盈利而沒有人情,也不懂得回饋這個社會,沒有負起提升大眾美感的責任,褻瀆了在這個地位上的價值也一併抹煞掉大眾看到好的藝術設計的權力。

最後想提醒各位插畫師或是平面設計師們,千萬不要忘記了!包裝上沒有任何設計、繪本沒有任何圖樣與排版、廣告只有一片空白而沒有設計感的字體,是不會有任何人想對這些廠商消費的!插畫設計師們應該團結,不接不尊重藝術設計和沒有給予合理價碼的廠商設計案,這些急需藝術設計推銷的廠商才會意識到我們的重要性。 華人市場還有很長的路要走⋯ 畢竟插畫家和設計師們,自己都在坑殺自己人,還有什麼好抱怨?不專業的客戶是被不專業的插畫家和設計師慣出來的。而不尊重原創藝術的大環境,往往就只會有廠商要求你模仿別人風格甚至是抄襲,漸漸就沒有了自己的靈魂和原創性。

再透露一下:目前歐美網頁用刊物插畫是9000塊台幣以上的價格。

想在短時間找到特定布料出貨,全靠數據分析

陳富泉生產的格子布因品質穩定,成為多家國際精品的主要供應商。 

和明年產4百多萬碼格子布,僅2%內銷,為穩住訂單下足功夫。陳富泉舉例,某大精品為避免布料遭不肖人士製成假貨販售,剩餘布料都要求送往焚化爐燒燬,「他們付錢燒燬,燒時還要錄影存證,不能流到市面上。」

還有一次和明替Ralph Lauren生產格子海灘褲,但其中一條藍色格紋無法通過日照褪色測試被退貨,一接到電話,陳富泉與李桂林立刻飛往紐約救火,「我還記得那天碰上亂流,我們倆在機上痛苦得要死。」

「我們認為布料沒問題,因為不會有人連續日曬10幾個小時,可是品牌是無價的,人家有這個標準,是我們自己不對,該賠就賠。」認賠四百多萬元對代工廠來說不是小數目,「品牌認為我們很有guts(膽識),是值得信賴的工廠,單子越做越大。」但也因此李桂林的辦公室內,迄今仍放了好幾咖行李箱,以備隨時出國。

陳富泉(左)與李桂林(右)是大學班對,也是共同打拚事業的好夥伴。 

陳富泉個性豪邁爽朗,與員工交流一點也沒有老闆的架子,談起這堂賠400萬元的課,他直言:「那是一張很大的單子,但我是B型雙魚座,我太太都說我比較浪漫,其實我認為事情能解決就好。」

好奇他曾做過什麼浪漫的事?看遍大風大浪的老闆卻有些害羞,他說自己對星象沒有研究,但提到家人的星座、血型卻記得清楚仔細,「像我太太是A型巨蟹座,她真的很愛家。」

我的產品很好,可是在台灣生產好像成了原罪,人家會問你憑什麼比中國、比東南亞還貴?

不過,快時尚風行,以往不競逐速度的精品也跟著快起來,交期從90天縮短至35天。拉開和明位於北市敦化南路辦公室內的布料庫,十幾萬條花色不同的格子布,幾乎是這條路上最貴的倉庫,想在短時間找到特定布料出貨,全靠數據分析。去年和明決定導入Google雲端機器學習,將所有布料建檔,精準確認交期、採購,減少過去重新設計、打樣的時間。

因不直接生產成衣,陳富泉只要出國看到自家布料生產的衣服就會買回來。

跟上速度與潮流,但代工業者也有品牌夢,「我的產品很好,可是在台灣生產好像成了原罪,人家會問你憑什麼比中國、比東南亞還貴?」陳富泉說。

「每一塊布我都是很有感情的,就好像一個女兒,我把她嫁得很好,可是沒辦法去看她過得好不好?所以只要出國看到我們布料做成的衣服我就會買回來。」他苦笑,「在工廠看布沒感覺,一做成衣服,你會覺得怎麼這麼漂亮?」

Omni-Channel Retail 全通路零售 (全渠道零售)

自從智慧手機普及以來,越來越多零售、服務業者在講 O2O,所謂 Online-to-Offline,亦即把消費者從線上平台引導到線下商店,或是 Offline-to-Online,也就是把線下商品放到線上去銷售。

可惜多數時候,這兩種觀點都是見樹不見林的。

線上線下沒有分界

首先,台灣智慧手機普及近 80%、民眾平均每天滑手機 3 小時,都是世界第一。在這樣網路極度普及的社會,線上線下基本是同一群消費者,他們這一秒在你店裡,下一秒就在上網,這一分鐘在社群網站,下一分鐘又在通訊軟體。把這些人的消費決策歷程,僅用線上、線下兩步驟區隔,往往太過簡化。

線上線下競爭一樣激烈

另一方面,Online 和 Offline 不僅各有生態,且都極度競爭。相較於純網路販售,把消費者從線上引到線下完成交易,不僅時間拉長,到達實體店點過程中,也有太多誘惑可能讓他改變心意。同樣道理,線下產品與服務要在網路上銷售,也得面對網路原生同業的競爭,線下積累的優勢,來到數位世界不一定仍舊成立,有時甚至成為累贅。因此,O2O 理想上可以擴大市場 ,但由於要同時征服兩個高度競爭的異質環境,實務上往往反而事倍功半。

全通路零售

因此在近年來,在美國零售業,大家已經開始用更進步的觀念去看線上與線下的協作,其中一個漸漸成為主流的思維,稱作 Omni-Channel Retail,翻譯成中文稱為「全通路零售」。

在全通路零售的世界,消費者變成工作的核心,無論他透過線上的品牌網站、品牌 Apps、Facebook、YouTube、Instagram 等社群媒體,Snapchat、FB Messenger、簡訊等通訊平台,或是線下的街邊店、百貨專櫃、零時店點、活動現場,都能得到和諧且交響的品牌體驗。此外,品牌延伸出的這些服務體系,不僅能夠認識他是誰,更能根據他的個性、興趣、購買習慣,以及先前走過的決策歷程,提供給他當下最適合的資訊與服務。

全通路購物車

這樣多通道緊密協作的消費體系,可以做到許多非常體貼的服務。舉例來說,全通路購物車就是其中最基本的功能,換言之,當你把某個商品加入購物車後,無論你在桌面官網、行動官網、App,甚至未來在實體店面,只要登入之後,都可以看到這個商品在你的購物車裡面。

這個功能雖然基本,但在時間越來越碎片化的今日,對消費者而言是日益重要。因為你這一秒可能在家裡電腦上購物,出門後在捷運上又用手機繼續,到了公司開始工作、開會,午休時想到又用辦公室電腦登入去看看,最後晚上回家才拿起平板結帳。這些通路上,如果沒有統一的購物車,那麼你每次都得從零開始,完成消費的意願與機率當然大大降低。

個人化售前、售後服務

而當品牌旗下的各個通路已經認識某個顧客,那麼個人化便可以往消費的上、下游服務移動,換言之,提供專屬的售前、售後服務。個性化服務 Amazon 已經行之有年,但隨著智慧手機、社群媒體的普及,帶來對每個消費者更全面的理解,個人化將會越來越準確,也越來越廣泛下放。另一方面,Disney 樂園用官網、App 與智慧手環協作所組成的個人化體系,某種程度就是未來全通路服務模式的雛形。類似的架構,可以預期的,將會漸漸在零售、服務業中擴散開來。

品牌是核心

而當消費者經常在不同通路中與你的企業互動、交易,除了提供給他們個性化的服務,另一個重點,就是一致的品牌印象。換言之,當通路變得複雜,一個品牌的中心思想如果不明確、或是不堅定,就容易顯露出來,放大 100 倍後,好壞品牌高下立見。因此,回到核心,企業必須對自己經營的品牌,有明確且優秀的定義,才能在零售與服務往全通路整合的大洗牌過程中,成為領先者的角色。

全渠道零售的興起

市場研究機構 Insight Express 的數據顯示,2011年人們在實體店購物時,有59%的智能手機用戶會利用移動終端尋找更優惠的價格,這一比例比2010年增加了40%。數字營銷機構ComScore的調查顯示,在進入實體零售店的購物者中,有近六成會選擇隨後在網上購物。零售巨頭沃爾瑪CEO Mike Duke稱,SoLoMo正將零售業帶入『價格透明新紀元』,零售商正處於SoLoMoMe(social社交+local本地化+mobile移動+personalized個性化)經濟時代的起點。

為了應對這一挑戰,百貨業必須脫胎換骨,因而全渠道零售已經成為必然選擇。歐美百貨業已經完成了從單一渠道向多渠道的進化,目前正向全渠道零售階段過渡。所謂全渠道零售,是指以消費者為中心,利用所有的銷售渠道,將消費者在各種不同渠道的購物體驗無縫鏈接,同時將消費過程的愉悅性最大化。因此,顧客可以同時利用一切的渠道,如實體店、目錄、呼叫中心、互聯網以及手機等,隨時隨地地購物。

根據市場研究機構 IDC Retail Insights最近的研究結果,全渠道消費者是標準的黃金消費者。相對於單渠道消費者,多渠道消費者平均要多消費 15%-30%。而相比於多渠道消費者,全渠道消費者平均要多消費 20%。更為重要的是,全渠道消費者的顧客忠誠度要遠遠高於前兩者,並且還會通過社交媒體和線上活動影響更多的顧客。

如果傳統百貨商想在將來繼續運作下去,那麼他們必須擁抱全渠道零售的到來,要通過物理的和虛擬的渠道,把購物轉變成一個充滿趣味,又有著強烈的情感聯繫的購物體驗。

Omni-Channel 的實作藉由 Web API: https://21st.each1.net/2018/07/restful-web-api.html



全通路 VS.多通路

Omni-Channel Retail (全通路零售) 在美國零售業中已是主流思維,台灣大多數的零售業者會在 PChome 商店街、momo 購物網、Yahoo 超級商城上開店,也都擁有自己的品牌官方網站,甚至少數業者擁有品牌 App ,但若只停留在這個階段,還不能算是全通路,僅能稱作是 Multi-Channel Retail(多通路零售),但「多通路」早已是十多年前的零售思維,早在 2004 年全球知名零售業研究機構 STORES 曾在趨勢研究報告中指出「電腦普及與網際網路基礎建設日臻成熟,線上零售將成為未來零售業主流,也將使得零售業者紛紛走向虛擬和實體通路互用之多通路零售發展。」

之所以還有零售業者停留在多通路的思維,恐怕是因為尚未明白 Omni-Channel Retail 的真理,多通路之間彼此若有緊密的整合,不管是在訊息的傳遞、會員的資料、會員在多通路上的行為等,彼此並非獨立運行,那這就是所謂的全通路,簡單來說,就是能從 C2B(Customer to Business) 的角度出發,讓會員在不同的通路上,皆能享有更完美的購物經驗。





如何防禦 CSRF (Cross Site Request Forgery) 跨站請求偽造


client side 的 Double Submit Cookie

https://blog.techbridge.cc/2017/02/25/csrf-introduction/

https://security.stackexchange.com/questions/59470/double-submit-cookies-vulnerabilities


反思:
本文作者文末針對 SPA 的需求,提出由 client side 來生成 csrf token,
這部分恐怕是有疑慮的,因為由 client side 來生成 csrf token, cookie 的 HttpOnly 參數就只能設定為 false... 那麼,駭客就能拿到這個 csrf token 了 ?


以下為存檔備份,以防資料來源網站撤除資料,平時到出處網站閱讀在視覺體驗方面會比較舒適:

前言

最近剛好碰到一些 CSRF 的案例,趁著這次機會好好研究了一下。深入研究之後才發現這個攻擊其實滿可怕的,因為很容易忽略它。但幸好現在有些 Framework 都有內建防禦 CSRF 的功能,可以很簡單的開啟。
但儘管如此,我認為還是有必要瞭解一下 CSRF 到底在幹嘛,是透過怎樣的手段攻擊,以及該如何防禦。就讓我們先來簡單的介紹一下它吧!
CSRF 是一種 Web 上的攻擊手法,全稱是 Cross Site Request Forgery,跨站請求偽造。不要跟 XSS 搞混了,他們兩種是不同的東西,那到底什麼是 CSRF 呢?先從我自身的一個案例談起好了。

偷懶的刪除功能

以前我有做個一個簡單的後台頁面,就想成是一個部落格吧!可以發表、刪除以及編輯文章,介面大概長得像這樣:
delete
可以看到刪除的那個按鈕,點下去之後就可以把一篇文章刪掉。當初因為偷懶,想說如果我把這個功能做成 GET,我就可以直接用一個連結完成刪除這件事,在前端幾乎不用寫到任何程式碼:





1
<a href='/delete?id=3'>刪除</a>

很方便對吧?然後我在網頁後端那邊做一下驗證,驗證 request 有沒有帶 session id 上來,也驗證這篇文章是不是這個 id 的作者寫的,都符合的話才刪除文章。
嗯,聽起來該做的都做了啊,我都已經做到:「只有作者本人可以刪除自己的文章」了,應該很安全了,難道還有哪裡漏掉了嗎?
沒錯,的確是「只有作者本人可以刪除自己的文章」,但如果他不是自己「主動刪除」,而是在不知情的情況下刪除呢?你可能會覺得我在講什麼東西,怎麼會有這種事情發生,不是作者主動刪的還能怎麼刪?
好,我就來讓你看看還能怎麼刪!
今天假設小黑是一個邪惡的壞蛋,想要讓小明在不知情的情況下就把自己的文章刪掉,該怎麼做呢?
他知道小明很喜歡心理測驗,於是就做了一個心理測驗網站,並且發給小明。但這個心理測驗網站跟其他網站不同的點在於,「開始測驗」的按鈕長得像這樣:





1
<a href='https://small-min.blog.com/delete?id=3'>開始測驗</a>

小明收到網頁之後很開心,就點擊「開始測驗」。點擊之後瀏覽器就會發送一個 GET 請求給https://small-min.blog.com/delete?id=3,並且因為瀏覽器的運行機制,一併把 small-min.blog.com 的 cookie 都一起帶上去。
Server 端收到之後檢查了一下 session,發現是小明,而且這篇文章也真的是小明發的,於是就把這篇文章給刪除了。
這就是 CSRF,你現在明明在心理測驗網站,假設是 https://test.com 好了,但是卻在不知情的狀況下刪除了 https://small-min.blog.com 的文章,你說這可不可怕?超可怕!
這也是為什麼 CSRF 又稱作 one-click attack 的緣故,你只要點一下就中招了。
你可能會說:「可是這樣小明不就知道了嗎,不就連過去部落格了?不符合『不知情的狀況』啊!」
好,那如果我們改成這樣呢:





1
2
<img src='https://small-min.blog.com/delete?id=3' width='0' height='0' />
<a href='/test'>開始測驗</a>

在開啟頁面的同時,一樣發送一個刪除的 request 出去,但這次小明是真的完全不知道這件事情。這樣就符合了吧!
CSRF 就是在不同的 domain 底下卻能夠偽造出「使用者本人發出的 request」。要達成這件事也很簡單,因為瀏覽器的機制,你只要發送 request 給某個網域,就會把關聯的 cookie 一起帶上去。如果使用者是登入狀態,那這個 request 就理所當然包含了他的資訊(例如說 session id),這 request 看起來就像是使用者本人發出的。

那我把刪除改成 POST 不就好了嗎?

沒錯,聰明!我們不要那麼懶,好好把刪除的功能做成 POST,這樣不就無法透過 <a> 或是 <img> 來攻擊了嗎?除非有哪個 HTML 元素可以發送 POST request!
有,正好有一個,就叫做 form。





1
2
3
4
<form action="https://small-min.blog.com/delete" method="POST">
<input type="hidden" name="id" value="3"/>
<input type="submit" value="開始測驗"/>
</form>

小明點下去以後,照樣中招,一樣刪除了文章。你可能又會疑惑說,但是這樣小明不就知道了嗎?我跟你一樣很疑惑,於是我 Google 到了這篇:Example of silently submitting a POST FORM (CSRF)
這篇提供的範例如下,網頁的世界真是博大精深:





1
2
3
4
5
6
<iframe style="display:none" name="csrf-frame"></iframe>
<form method='POST' action='https://small-min.blog.com/delete' target="csrf-frame" id="csrf-form">
<input type='hidden' name='id' value='3'>
<input type='submit' value='submit'>
</form>
<script>document.getElementById("csrf-form").submit()</script>

開一個看不見的 iframe,讓 form submit 之後的結果出現在 iframe 裡面,而且這個 form 還可以自動 submit,完全不需要經過小明的任何操作。
到了這步,你就知道改成 POST 是沒用的。

那我後端改成只接收 json 呢?

聰明的你靈機一動:「既然在前端只有 form 可以送出 POST 的話,那我的 api 改成用 json 收資料不就可以了嗎?這樣總不能用 form 了吧!」
spring 的 document告訴你:這還是沒用的!





1
2
3
4
5
<form action="https://small-min.blog.com/delete" method="post" enctype="text/plain">
<input name='{"id":3, "ignore_me":"' value='test"}' type='hidden'>
<input type="submit"
value="delete!"/>
</form>

這樣子會產生如下的 request body:





1
2
3
{ "id": 3,
"ignore_me": "=test"
}

但這邊值得注意的一點是,form能夠帶的 content type 只有三種:application/x-www-form-urlencoded, multipart/form-data 跟 text/plain。在上面的攻擊中我們用的是最後一種,text/plain,如果你在你的後端 Server 有檢查這個 content type 的話,是可以避免掉上面這個攻擊的。
只是,上面這幾個攻擊我們都還沒講到一種情況:如果你的 api 接受 cross origin 的 request 呢?
意思就是,如果你的 api 的 Access-Control-Allow-Origin 設成 * 的話,代表任何 domain 都可以發送 ajax 到你的 api server,這樣無論你是改成 json,或甚至把 method 改成 PUT, DELETE 都沒有用。
我們舉的例子是刪除文章,這你可能覺得沒什麼,那如果是銀行轉帳呢?攻擊者只要在自己的網頁上寫下轉帳給自己帳號的 code,再把這個網頁散佈出去就好,就可以收到一大堆錢。
講了這麼多,來講該怎麼防禦吧!先從最簡單的「使用者」開始講。

使用者的防禦

CSRF 攻擊之所以能成立,是因為使用者在被攻擊的網頁是處於已經登入的狀態,所以才能做出一些行為。雖然說這些攻擊應該由網頁那邊負責處理,但如果你真的很怕,怕網頁會處理不好的話,你可以在每次使用完網站就登出,就可以避免掉 CSRF。
或者呢,關閉執行 js 或把上面這些 pattern 的程式碼過濾掉不要執行,也是一個方法(但應該很難判定哪些是 CSRF 攻擊的程式碼)。
所以使用者能做的其實有限,真的該做事的是 Server 那邊!

Server 的防禦

CSRF 之所以可怕是因為 CS 兩個字:Cross Site,你可以在任何一個網址底下發動攻擊。CSRF 的防禦就可以從這個方向思考,簡單來說就是:「我要怎麼擋掉從別的 domain 來的 request」
你仔細想想,CSRF 的 reuqest 跟使用者本人發出的 request 有什麼區別?區別在於 domain 的不同,前者是從任意一個 domain 發出的,後者是從同一個 domain 發出的(這邊假設你的 api 跟你的前端網站在同一個 domain)

檢查 Referer

request 的 header 裡面會帶一個欄位叫做 referer,代表這個 request 是從哪個地方過來的,可以檢查這個欄位看是不是合法的 domain,不是的話直接 reject 掉即可。
但這個方法要注意的地方有三個,第一個是有些瀏覽器可能不會帶 referer,第二個是有些使用者可能會關閉自動帶 referer 的這個功能,這時候你的 server 就會 reject 掉由真的使用者發出的 request。
第三個是你判定是不是合法 domain 的程式碼必須要保證沒有 bug,例如:





1
2
3
4
const referer = request.headers.referer;
if (referer.indexOf('small-min.blog.com') > -1) {
// pass
}

你看出上面這段的問題了嗎?如果攻擊者的網頁是small-min.blog.com.attack.com的話,你的檢查就破功了。
所以,檢查 referer 並不是一個很完善的解法

加上圖形驗證碼、簡訊驗證碼等等

就跟網路銀行轉帳的時候一樣,都會要你收簡訊驗證碼,多了這一道檢查就可以確保不會被 CSRF 攻擊。
圖形驗證碼也是,攻擊者並不知道圖形驗證碼的答案是什麼,所以就不可能攻擊了。
這是一個很完善的解決方法,但如果使用者每次刪除 blog 都要打一次圖形驗證碼,他們應該會煩死吧!

加上 CSRF token

要防止 CSRF 攻擊,我們其實只要確保有些資訊「只有使用者知道」即可。那該怎麼做呢?
我們在 form 裡面加上一個 hidden 的欄位,叫做csrftoken,這裡面填的值由 server 隨機產生,並且存在 server 的 session 中。





1
2
3
4
5
<form action="https://small-min.blog.com/delete" method="POST">
<input type="hidden" name="id" value="3"/>
<input type="hidden" name="csrftoken" value="fj1iro2jro12ijoi1"/>
<input type="submit" value="刪除文章"/>
</form>

按下 submit 之後,server 比對表單中的csrftoken與自己 session 裡面存的是不是一樣的,是的話就代表這的確是由使用者本人發出的 request。這個 csrftoken 由 server 產生,並且每一段不同的 session 就應該要更換一次。
那這個為什麼可以防禦呢?因為攻擊者並不知道 csrftoken 的值是什麼,也猜不出來,所以自然就無法進行攻擊了。
可是有另外一種狀況,假設你的 server 支持 cross origin 的 request,會發生什麼事呢?攻擊者就可以在他的頁面發起一個 request,順利拿到這個 csrf token 並且進行攻擊。不過前提是你的 server 接受這個 domain 的 request。
接著讓我們來看看另外一種解法
上一種解法需要 server 的 state,亦即 csrf token 必須被保存在 server 當中,才能驗證正確性。而現在這個解法的好處就是完全不需要 server 儲存東西。
這個解法的前半段與剛剛的相似,由 server 產生一組隨機的 token 並且加在 form 上面。但不同的點在於,除了不用把這個值寫在 session 以外,同時也讓 client side 設定一個名叫 csrftoken 的 cookie,值也是同一組 token。





1
2
3
4
5
6
7
Set-Cookie: csrftoken=fj1iro2jro12ijoi1
<form action="https://small-min.blog.com/delete" method="POST">
<input type="hidden" name="id" value="3"/>
<input type="hidden" name="csrftoken" value="fj1iro2jro12ijoi1"/>
<input type="submit" value="刪除文章"/>
</form>

你可以仔細思考一下 CSRF 攻擊的 request 與使用者本人發出的 request 有什麼不一樣?不一樣的點就在於,前者來自不同的 domain,後者來自相同的 domain。所以我們只要有辦法區分出這個 request 是不是從同樣的 domain 來,我們就勝利了。
而 Double Submit Cookie 這個解法正是從這個想法出發。
當使用者按下 submit 的時候,server 比對 cookie 內的 csrftoken 與 form 裡面的 csrftoken,檢查是否有值並且相等,就知道是不是使用者發的了。
為什麼呢?假設現在攻擊者想要攻擊,他可以隨便在 form 裡面寫一個 csrf token,這當然沒問題,可是因為瀏覽器的限制,他並不能在他的 domain 設定 small-min.blog.com 的 cookie 啊!所以他發上來的 request 的 cookie 裡面就沒有 csrftoken,就會被擋下來。
當然,這個方法看似好用,但也是有缺點的,可以參考:Double Submit Cookies vulnerabilities,攻擊者如果掌握了你底下任何一個 subdomain,就可以幫你來寫 cookie,並且順利攻擊了。
會特別提到 client side,是因為我之前所碰到的專案是 Single Page Application,上網搜尋一下就會發現有人在問:「SPA 該如何拿到 CSRF token?」,難道要 server 再提供一個 api 嗎?這樣好像有點怪怪的。
但是呢,我認為我們可以利用 Double Submit Cookie 的精神來解決這個問題。而解決這問題的關鍵就在於:由 client side 來生 csrf token。就不用跟 server api 有任何的互動。
其他的流程都跟之前一樣,生成之後放到 form 裡面以及寫到 cookie。或者說如果你是 SPA 的話,也可以把這資訊直接放到 request header,你就不用在每一個表單都做這件事情,只要統一加一個地方就好。
事實上,我自己常用的 library axios 就有提供這樣的功能,你可以設置 header 名稱跟 cookie 名稱,設定好以後你每一個 request,它都會自動幫你把 header 填上 cookie 裡面的值。





1
2
3
4
5
// `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default

那為什麼由 client 來生這個 token 也可以呢?因為這個 token 本身的目的其實不包含任何資訊,只是為了「不讓攻擊者」猜出而已,所以由 client 還是由 server 來生成都是一樣的,只要確保不被猜出來即可。Double Submit Cookie 靠的核心概念是:「攻擊者的沒辦法讀寫目標網站的 cookie,所以 request 的 csrf token 會跟 cookie 內的不一樣」

browser 本身的防禦

我們剛剛提到了使用者自己可以做的事、網頁前後端可以做的事情,那瀏覽器呢?之所以能成立 CSRF,是因為瀏覽器的機制所導致的,有沒有可能從瀏覽器方面下手,來解決這個問題呢?
有!而且已經有了。而且啟用的方法非常非常簡單。
Google 在 Chrome 51 版的時候正式加入了這個功能:SameSite cookie,對詳細運行原理有興趣的可參考:draft-west-first-party-cookies-07。
先引一下 Google 的說明:
Same-site cookies (ne “First-Party-Only” (ne “First-Party”)) allow servers to mitigate the risk of CSRF and information leakage attacks by asserting that a particular cookie should only be sent with requests initiated from the same registrable domain.
啟用這個功能有多簡單?超級無敵簡單。
你原本設置 Cookie 的 header 長這樣:





1
Set-Cookie: session_id=ewfewjf23o1;

你只要在後面多加一個 SameSite 就好:





1
Set-Cookie: session_id=ewfewjf23o1; SameSite

但其實 SameSite 有兩種模式,Lax跟Strict,默認是後者,你也可以自己指定模式:





1
2
Set-Cookie: session_id=ewfewjf23o1; SameSite=Strict
Set-Cookie: foo=bar; SameSite=Lax

我們先來談談默認的 Strict模式,當你加上 SameSite 這個關鍵字之後,就代表說「我這個 cookie 只允許 same site 使用,不應該在任何的 cross site request 被加上去」。
意思就是你加上去之後,我們上面所講的<a href="">, <form>, new XMLHttpRequest,只要是瀏覽器驗證不是在同一個 site 底下發出的 request,全部都不會帶上這個 cookie。
可是這樣其實會有個問題,連<a href="..."都不會帶上 cookie 的話,當我從 Google 搜尋結果或者是朋友貼給我的連結點進某個網站的時候,因為不會帶 cookie 的關係,所以那個網站就會變成是登出狀態。這樣子的使用者體驗非常不好。
有兩種解法,第一種是跟 Amazon 一樣,準備兩組不同的 cookie,第一組是讓你維持登入狀態,第二組則是做一些敏感操作的時候會需要用到的(例如說購買、設定帳戶等等)。第一組不設定 SameSite,所以無論你從哪邊來,都會是登入狀態。但攻擊者就算有第一組 cookie 也不能幹嘛,因為不能做任何操作。第二組因為設定了 SameSite 的緣故,所以完全避免掉 CSRF。
但這樣子還是有點小麻煩,所以你可以考慮第二種,就是調整為 SameSite 的另一種模式:Lax。
Lax 模式放寬了一些限制,例如說<a>, <link rel="prerender">, <form method="GET"> 這些都還是會帶上 cookie。但是 POST 方法 的 form,或是只要是 POST, PUT, DELETE 這些方法,就不會帶上 cookie。
所以一方面你可以保有彈性,讓使用者從其他網站連進你的網站時還能夠維持登入狀態,一方面也可以防止掉 CSRF 攻擊。但 Lax 模式之下就沒辦法擋掉 GET 形式的 CSRF,這點要特別注意一下。
講到這種比較新的東西,相信大家一定都很想知道瀏覽器的支援度如何,caniuse告訴我們說:目前只有 Chrome 支援這個新的特性(畢竟是 Google 自己推的方案,自己當然要支持一下)。
雖然瀏覽器的支援度不太高,但日後其他瀏覽器可能也會跟進實做這個方案,不妨在現在就把 SameSite 加上去,以後就不用再為 CSRF 煩惱了。
我其實只是大略的介紹一下,draft-west-first-party-cookies-07 裡面講到很多細節,例如說到底怎樣算是 cross site? 一定要在同一個 domain 嗎?那 sub domain 行不行?
好奇的可以自己研究一下,或者是這篇:SameSite Cookie,防止 CSRF 攻击也有提到。
SameSite 相關的參考資料:
  1. Preventing CSRF with the same-site cookie attribute
  2. 再见,CSRF:讲解set-cookie中的SameSite属性
  3. SameSite Cookie,防止 CSRF 攻击
  4. SameSite——防御 CSRF & XSSI 新机制
  5. Cross-Site Request Forgery is dead!

總結

這篇主要介紹了 CSRF 的攻擊原理以及兩種防禦方法,針對比較常見的場景做介紹。一般在做網頁開發的時候,比起 XSS,CSRF 是一個比較常被忽略的重點。在網頁上有任何比較重要的操作時,都要特別留意是否有被 CSRF 的風險。
這次找了很多參考資料,但發現跟 CSRF 有關的文章其實都大同小異,想知道更細節的地方需要花很多的心力去找,但幸好 Stackoverflow 上面也有不少資料可以參考。因為我在資訊安全這塊沒有涉獵太多,如果文章有哪部分講錯的話,還麻煩各位在留言不吝指出。
也感謝我朋友 shik 的指點,告訴我有 SameSite 這麼一個東西,讓我補上最後一段。
希望這篇文章能讓大家對 CSRF 有更全面的認識。

參考資料

  1. Cross-Site Request Forgery (CSRF)
  2. Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet
  3. 一次较为深刻的CSRF认识
  4. [技術分享] Cross-site Request Forgery (Part 2)
  5. Spring Security Reference
  6. CSRF 攻击的应对之道

程式語言編年史

程式語言編年史原文 下面這張圖片描繪了整個程式語言的歷史。包括各種程式語言的發明人、程式語言的特點和適用領域、被什麼網站或公司使用等 (檢視 完整高清圖 )。 之所以會有那麼多不同的程式語言是因為設計程式語言的初衷不同、對語言學習曲線的追求不同、不同程式之間的執行成本差異...