Jan 2025【日本東北】溫泉三昧之旅① 在大雪飄落的雪國,追尋秘湯之宿與極上美食(秋田~探訪有日本溫泉界頂點之稱的秘湯乳頭溫泉鶴之湯)

圖片
飛機穿過厚重的雲層,眼前的世界瞬間變成一片白茫茫。大片的雪花,像是鵝毛般漫天飛舞,所有景物都披上了一層潔白的冬衣,只剩下模糊的輪廓,分不清是房屋、樹木還是道路。 下了飛機,一股寒風迎面而來,我不禁打了個寒顫,但也同時被眼前這片銀裝素裹的世界深深吸引。這就是東北的冬天啊!雖然寒冷,但卻充滿了獨特的魅力,如同一個冰雪的童話世界,等待著我們去探索。 我知道,這場大雪只是個開始,接下來幾天的旅程,將會是一場與冰雪共舞之旅。但我已經迫不及待地想要擁抱這片雪國大地,體驗這份獨一無二的冬季風情。 秋田位於日本本州島的北部,瀕臨日本海,冬天受到西伯利亞冷氣團的影響,降雪量非常豐沛。聽說這裡的雪可以堆積到好幾公尺高呢! 秋田的冬天,雖然寒冷,卻充滿了活力和熱情。首先,你可以在森吉山滑雪場滑雪,從雪道上俯衝而下,感受速度與激情!聽說那裡的樹冰也很有名,可惜這次我們沒時間去欣賞。 除了滑雪,秋田還有許多有趣的冬季活動。在橫手市的「橫手雪屋祭」,你可以看到各式各樣的雪屋,晚上點上燈,更是夢幻!聽說在雪屋裡還可以喝甜酒、吃麻糬呢! 當然,來到秋田,也別忘了品嚐當地的冬季美食。熱騰騰的米棒鍋,配上秋田特產的比內地雞和新鮮蔬菜,暖胃又暖心!還有,在寒冬中泡個暖呼呼的溫泉,更是人生一大享受! 剛踏進秋田機場的入境大廳,我就被眼前一個氣勢磅礡的「生剝鬼」給震懾住了!他身披粗獷的稻草蓑衣,手持木棒和裝滿白色紙片的桶子,臉上那副紅色面具更是令人印象深刻:獠牙外露、怒目圓睜,彷彿下一秒就要衝過來似的。 「生剝鬼」(なまはげ)是秋田縣男鹿半島的傳統民俗人物,也是當地家喻戶曉的傳奇角色。據說,生剝鬼是山神的使者,每年除夕夜都會來到村莊,挨家挨戶地驅趕懶惰和邪惡,為人們帶來好運和豐收。他們會大聲吼叫:「有沒有愛哭的小孩?有沒有不聽話的小孩?」,嚇唬孩子們要乖乖聽話,認真學習。 雖然生剝鬼看起來很可怕,但他們其實是善良的,是來保護人們的。生剝鬼的形象也反映了秋田人民勤勞勇敢、不畏艱難的精神。 生剝鬼的故事世代相傳,至今已有數百年的歷史。每年除夕夜,男鹿半島的村民都會舉行「生剝鬼節」,年輕人會裝扮成生剝鬼的樣子,挨家挨戶地拜訪,祈求來年平安順遂。 接著,我們從機場搭乘路線巴士來到了秋田車站,上次來造訪這裡,已是十年前的往事了。一踏進車站,我就被眼前這隻巨大的秋田犬玩偶給吸引住!它憨態可掬地趴在車站大廳中央,吐著粉嫩...

Using Google OAuth with Youtube in your Rails Sites

OAuth allows the user to securely share data from provider sites (in this case google) to consumer sites (in this case your ruby on rails site). You can use OAuth to authenticate users or consume API’s on their behalf. Here we will have a look at both.

下面是實作Google OAuth驗證透過Youtube帳號登入Rails Website之過程,整個實作過程是建立在一個現有的Rails Project上(基本條件是必須包含現有的user record和登入/登出系統以及帳號管理機制)。ps. 如果你需要一個現成的Ruby on Rails使用者登入/註冊機制,我認為Authlogic是一個不錯的選擇。

About Authlogic:
http://www.binarylogic.com/category/my-projects/authlogic/
Authlogic Gem download:
http://github.com/binarylogic/authlogic/
Authlogic Example Project on Github:
http://github.com/binarylogic/authlogic_example/

在實作之前,首先我們需要到Google註冊頁面添加你的網域並驗證:
https://www.google.com/accounts/ManageDomains


我們可以使用RSA key來作為signature method,在*NIX或OS X平台上我們可以用openssl來產生RSA Keys(將www.example.com改成你的域名):
$ openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj '/C=US/ST=CA/L=San Francisco/CN=www.example.com' -keyout rsakey.pem -out rsacert.pem

Generating a 1024 bit RSA private key
.........++++++
.................++++++
writing new private key to 'rsakey.pem'

若要定義簽章方式,只需要在OAuth::Consumer instance中加入:signature_method和:private_key_file這兩個參數:用來分別定義簽章方式以及Private Key的存放路徑即可,此外還要記得require 'oauth/signature/rsa/sha1'。接下來將產生的rsacert.pem檔案上傳至Google的Manage Domains註冊頁面,然後我們可以將這兩個檔案複製到#{RAILS_ROOT}/config目錄下。

我們可以在#{RAILS_ROOT}/config/environment.rb中設定環境變數:

這是因為我們在Google註冊頁面將OAuth驗證的Callback地址設為http://www.example.com/authsub,而我們要將這個authsub方法放在users_controller中。

然後安裝oauth gem套件(我用的是0.4.0版本)和nokogiri gem套件,因為我們稍候會用到Nokogiri來解析Youtube傳回的XML內容:
$ sudo gem i oauth
$ sudo gem i nokogiri

最後我們要在User資料表中添加幾個欄位(youtube_username和oauth_token以及oauth_secret):
$ script/generate migration AddGoogleOauthToUsers

編輯遷移檔db/migrate/xxxxx_add_google_oauth_to_users.rb:

然後執行$ rake db:migrate新增欄位,之後我們可以給Users資料表新增一組youtube_username欄位的索引:


如果你要在網站上添加OAuth驗證機制,你應該真正了解OAuth的運作機制,如果只是複製這些程式碼到你的網站上讓它運作,將來你的網站可能會出問題!你可以到下面網址了解OAuth的運作方式。

Beginner’s Guide to OAuth:
http://hueniverse.com/oauth/

下面是Google OAuth運作機制的簡易流程圖:


下面是Google OAuth的運作機制,以Youtube服務為例:

Step1. The Request Token

首先我們需要一個OAuth::Consumer instance,它需要知道我們要和哪個網站溝通,以及該網站的Token-Services地址。我們將從這個instance中的get_request_token方法來獲取Request Token,此外Google還定義了一個scope參數來讓我們指定需要存取的Google服務。這邊我們要使用的是YouTube Data API,因此我們將scope參數設定為http://gdata.youtube.com即可。

Google服務列表請參考下面網址:
http://code.google.com/intl/zh-TW/apis/gdata/faq.html#AuthScopes

Step2. Authorize the Request Token

當使用者參考到request_token.authorize_url時,將會被導向Youtube的登入頁面(如果使用者尚未登入Google帳號),接下來使用者會被要求授權給應用程式。當使用者按下"允許授權"後,將會產生一個Authorized Request Token,接著Google服務(eq.Youtube)會傳遞一個oauth_verifier參數給我們應用程式的Oauth Callback(在我們的例子中是/authsub)來產生Access Token。之後我們就能利用這個Request Token來透過Youtube Data API存取使用者在Youtube網站上的個人資料。

Youtube (Google) 帳戶登入頁面:


授權應用程式頁面:


關於Youtube Data API請參考:
http://code.google.com/apis/youtube/getting_started.html#data_api

Step3. Time for coding!

首先在Application Controller中新增下面兩個方法:


然後在Users Controller新增下面的方法:


接著我們在User Model的password_required?方法添加下面內容,這是用來告訴資料庫當使用者是透過Google帳號註冊時,在建立新的User Record時不需要去驗證密碼欄位:


然後新增一個方法,用來在以後判斷某位使用者是否有Youtube帳號:


接下來修改/app/views/users/new.html.erb視圖,讓透過Google OAuth註冊帳號的使用者不需要填寫密碼設定欄位,因為他們日後可以透過Youtube帳號登入我們的網站:


然後同樣需要修改users/edit.html.erb視圖,讓透過Google OAuth驗證登入網站且尚未設定過密碼的使用者在設定密碼時不用填寫"現有密碼"欄位,因為他們的密碼是空的:


然後可以新增下面的內容,讓還沒有登入Youtube帳號的使用者可以連結至他們的Youtube帳號:


最後我們可以在Controller裡面對需要的Method添加 before_filter :load_oauth_user 來載入Application Controller裡的load_oauth_user方法。然後在特定的方法中加入下面內容:


Step4. What's next?

因為Access Token本身不會自動失效,除非使用者從Youtube網站上撤銷它,因此我們可以將使用者的Access Token存放在資料表中,之後當使用者透過Youtube帳號登入或是登入的使用者已經連結過Youtube帳號,我們就可以藉由Access Token在我們傳送給Youtube的HTTP Request中包含所需的authorization headers 而進一步從Youtube API來取得使用者的資料,例如可以再往站上顯示使用者的播放清單,上傳的影片,以及Youtube上面的好友列表等等。


參考資料:

Developer's Guide: Data API Protocol – OAuth for Web Applications
http://code.google.com/intl/zh-TW/apis/youtube/2.0/developers_guide_protocol_oauth.html

Google Data on Rails
http://code.google.com/intl/zh-TW/apis/gdata/articles/gdata_on_rails.html

Using Google OAuth in Ruby on Rails Sites
http://www.manu-j.com/blog/add-google-oauth-ruby-on-rails-sites/214/

Ruby, OAuth & YouTube
http://runerb.com/2010/01/12/ruby-oauth-youtube/

Youtube API
http://code.google.com/apis/youtube/overview.html

Using OAuth with the Google Data APIs
http://code.google.com/intl/zh-TW/apis/gdata/articles/oauth.html

熱門文章

[平成26年7月25日~28日]北アルプスの夏 ♪ 厳しく美しい後立山連峰南部3泊4日縦走★白馬八方から針ノ木岳(テント背負)

Mar 2025【新竹五峰】油羅山森呼吸:擁抱原始柳杉林秘境之美(羅山林道第一登山口往返)

Nov 2024【陽明山溫泉】老字號「馬槽花藝村」的溫泉管線已恢復|在木造山景湯屋享受半露天硫磺溫泉

Aug, 2023【桃園大溪】桃園小百岳編號23-溪洲山步道|適合訓練腳力、還能觀賞石門水庫的山水景色

Jan 2025【苗栗泰安】泰安警光山莊泡湯&彰化CP值極高的日本料理|沐藏料理所X海龍王|彰化板前料理 ♨️🍁🥢🍲

Sep 2024【桃園龜山】大棟山405高地散步(視野遼闊可遠眺大台北盆地,還能欣賞百萬夜景的好地方)

Jun 24~25, 2022【南橫三星】庫哈諾辛山+【南臺首嶽】關山(進涇橋登山口)|2天1夜野營登山

Feb, 2024【台中西區】桃太郎日本料理|隱身巷弄裡的39年老字號無菜單料理|食材新鮮、自然美味

Mar 2025【桃園復興】高遶溪古圳步道健行(第二期步道已完工,全長2.6公里)|隱藏版道地新疆料理~胡同彭家老舖新疆拉麵

2019, July 7~8【中國山東】老司機帶你攀登72位古代帝王曾登臨朝拜,以五嶽獨尊名揚天下的泰山(歷史典故+遊覽路線+遊記+照片)

文章列表

Contact

名稱

以電子郵件傳送 *

訊息 *