<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: unasuke (Yusuke Nakamura)</title>
    <description>The latest articles on DEV Community by unasuke (Yusuke Nakamura) (@unasuke).</description>
    <link>https://dev.to/unasuke</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F41484%2Faea40632-ed8c-4faf-841d-4ea8ec07be74.png</url>
      <title>DEV Community: unasuke (Yusuke Nakamura)</title>
      <link>https://dev.to/unasuke</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/unasuke"/>
    <language>en</language>
    <item>
      <title>omniauth-twitter2 gem - How to authenticate twitter account by OAuth 2.0 on your Rails app?</title>
      <dc:creator>unasuke (Yusuke Nakamura)</dc:creator>
      <pubDate>Wed, 30 Mar 2022 14:27:26 +0000</pubDate>
      <link>https://dev.to/unasuke/omniauth-twitter2-gem-how-to-authenticate-twitter-account-by-oauth-20-on-your-rails-app-5fm7</link>
      <guid>https://dev.to/unasuke/omniauth-twitter2-gem-how-to-authenticate-twitter-account-by-oauth-20-on-your-rails-app-5fm7</guid>
      <description>&lt;h2&gt;
  
  
  tl;dr
&lt;/h2&gt;

&lt;p&gt;I made this gem.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/unasuke" rel="noopener noreferrer"&gt;
        unasuke
      &lt;/a&gt; / &lt;a href="https://github.com/unasuke/omniauth-twitter2" rel="noopener noreferrer"&gt;
        omniauth-twitter2
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      OmniAuth strategy for authenticating with Twitter OAuth2
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;OmniAuth::Twitter2&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/unasuke/omniauth-twitter2/actions/workflows/main.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/unasuke/omniauth-twitter2/actions/workflows/main.yml/badge.svg" alt="test"&gt;&lt;/a&gt;
&lt;a href="https://github.com/unasuke/omniauth-twitter2/blob/main/LICENSE.txt" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ac3714419dde66cb49a627f11c02dad498aeb729f1d31c92c695c71ce1625437/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f756e6173756b652f6f6d6e69617574682d7477697474657232" alt="GitHub license"&gt;&lt;/a&gt;
&lt;a href="https://rubygems.org/gems/omniauth-twitter2" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5a851202f437bf5d970be5c440a84198ad7b52fd1060a0caed66c1a8558af62e/68747470733a2f2f62616467652e667572792e696f2f72622f6f6d6e69617574682d74776974746572322e737667" alt="Gem Version"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This gem provides a OmniAuth strategy for authenticating with Twitter OAuth2.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Add this line to your application's Gemfile:&lt;/p&gt;
&lt;div class="highlight highlight-source-ruby notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-en"&gt;gem&lt;/span&gt; &lt;span class="pl-s"&gt;'omniauth-twitter2'&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;And then execute:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ bundle install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or install it yourself as:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ gem install omniauth-twitter2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Rails&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-ruby notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;# config/initializers/omniauth.rb&lt;/span&gt;
&lt;span class="pl-v"&gt;Rails&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;application&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;config&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;middleware&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;OmniAuth&lt;/span&gt;::&lt;span class="pl-v"&gt;Builder&lt;/span&gt; &lt;span class="pl-k"&gt;do&lt;/span&gt;
  &lt;span class="pl-en"&gt;provider&lt;/span&gt; &lt;span class="pl-pds"&gt;:twitter2&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-c1"&gt;ENV&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-s"&gt;"TWITTER_CLIENT_ID"&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-c1"&gt;ENV&lt;/span&gt;&lt;span class="pl-kos"&gt;[&lt;/span&gt;&lt;span class="pl-s"&gt;"TWITTER_CLIENT_SECRET"&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-pds"&gt;callback_path&lt;/span&gt;: &lt;span class="pl-s"&gt;'/auth/twitter2/callback'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-pds"&gt;scope&lt;/span&gt;: &lt;span class="pl-s"&gt;"tweet.read users.read"&lt;/span&gt;
&lt;span class="pl-k"&gt;end&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Auth Hash&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-ruby notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;  &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-s"&gt;"provider"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"twitter2"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"uid"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"108252390"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"info"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-s"&gt;"name"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"うなすけ"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"email"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-c1"&gt;nil&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"nickname"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"yu_suke1994"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"description"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"帰って寝たい"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"image"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"https://pbs.twimg.com/profile_images/580019517608218624/KzEZSzUy_normal.jpg"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"urls"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
        &lt;span class="pl-s"&gt;"Website"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"https://t.co/NCFLB8wDkx"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
        &lt;span class="pl-s"&gt;"Twitter"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"https://x.com/yu_suke1994"&lt;/span&gt;
      &lt;span class="pl-kos"&gt;}&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"credentials"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-s"&gt;"token"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-s"&gt;"TOKENTOKENTOKENTOKENTOKENTOKEN"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"expires_at"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-c1"&gt;1642016242&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"expires"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-c1"&gt;true&lt;/span&gt;
    &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-s"&gt;"extra"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-s"&gt;"raw_info"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
        &lt;span class="pl-s"&gt;"data"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
          &lt;span class="pl-s"&gt;"profile_image_url"&lt;/span&gt; &lt;span class="pl-c1"&gt;=&amp;gt;&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/unasuke/omniauth-twitter2" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This gem is one of the OmniAuth strategies for Twitter, using OAuth 2.0 for the authentication protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  We have omniauth-twitter gem. Why this gem?
&lt;/h2&gt;

&lt;p&gt;Yes, the omniauth-twitter gem is a well-maintained, widely-used gem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/arunagw/omniauth-twitter" rel="noopener noreferrer"&gt;https://github.com/arunagw/omniauth-twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But, omniauth-twitter uses OAuth 1.0a.&lt;/p&gt;

&lt;h2&gt;
  
  
  Twitter OAuth 2.0 GA from 2021-12-15
&lt;/h2&gt;

&lt;p&gt;When 2021-12-15, Twitter announced OAuth 2.0 General Availability.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1470834775019515907-69" src="https://platform.twitter.com/embed/Tweet.html?id=1470834775019515907"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1470834775019515907-69');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1470834775019515907&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;And we can use "new fine-grained permission scopes" at the release.&lt;/p&gt;

&lt;p&gt;We could choose those three kinds of scopes in the older permission scope. That's too rough.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read&lt;/li&gt;
&lt;li&gt;Read and Write&lt;/li&gt;
&lt;li&gt;Read and write and Direct message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgifpkpvuoz520pjzfdb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgifpkpvuoz520pjzfdb.png" alt="OAuth 1.0a permission scopes" width="616" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now, We can choose &lt;strong&gt;enough permissions&lt;/strong&gt; from the list on OAuth 2.0 (through Twitter API V2)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code" rel="noopener noreferrer"&gt;https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tweet.read&lt;/code&gt;, &lt;code&gt;tweet.write&lt;/code&gt;, &lt;code&gt;tweet.moderate.write&lt;/code&gt;, &lt;code&gt;users.read&lt;/code&gt;, &lt;code&gt;follows.read&lt;/code&gt;, &lt;code&gt;follows.write&lt;/code&gt;, &lt;code&gt;offline.access&lt;/code&gt;, &lt;code&gt;space.read&lt;/code&gt;, &lt;code&gt;mute.read&lt;/code&gt;, &lt;code&gt;mute.write&lt;/code&gt;, &lt;code&gt;like.read&lt;/code&gt;, &lt;code&gt;like.write&lt;/code&gt;, &lt;code&gt;list.read&lt;/code&gt;, &lt;code&gt;list.write&lt;/code&gt;, &lt;code&gt;block.read&lt;/code&gt;, &lt;code&gt;block.write&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OK, how to use twitter with OAuth 2.0 with my rails app?
&lt;/h2&gt;

&lt;p&gt;I created a gem, "omniauth-twitter2". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/unasuke/omniauth-twitter2" rel="noopener noreferrer"&gt;https://github.com/unasuke/omniauth-twitter2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of the omniauth strategies, so it's easy to integrate your rails app if you use omniauth (or devise?)&lt;/p&gt;

&lt;p&gt;("2" means OAuth 2.0, not means successor of "omniauth-twitter" gem. because the gem still working everywhare!)&lt;/p&gt;

&lt;p&gt;And I have created a sample application that uses omniauth and omniauth-twitter2.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL: &lt;a href="https://twitter-login-app.onrender.com/" rel="noopener noreferrer"&gt;https://twitter-login-app.onrender.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code: &lt;a href="https://github.com/unasuke/twitter-login-app" rel="noopener noreferrer"&gt;https://github.com/unasuke/twitter-login-app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This app only signs in with twitter, but it's enough to show how to implement "sign in with Twitter".&lt;/p&gt;

&lt;h2&gt;
  
  
  Attention
&lt;/h2&gt;

&lt;p&gt;If you want to use OAuth 2.0 API in your twitter app, you should move your app to under "Project". You can't use OAuth 2.0 in your app if the app is still a "Standalone app".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fro4p0uaev4dm3l83o265.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fro4p0uaev4dm3l83o265.png" alt="twitter developer portal" width="800" height="704"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;...And I'm not a specialist in the authentication. Please give me a pull request or issue if you found a bug.&lt;/p&gt;




&lt;p&gt;I'm glad if you star the GitHub repository or share the post, if you want!&lt;/p&gt;

&lt;p&gt;📝 Original post: &lt;a href="https://blog.unasuke.com/2022/how-to-authenticate-twitter-account-by-oauth-2/" rel="noopener noreferrer"&gt;https://blog.unasuke.com/2022/how-to-authenticate-twitter-account-by-oauth-2/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>omniauth</category>
      <category>twitter</category>
    </item>
  </channel>
</rss>
