javascript - Twitter 登录的弹出窗口

标签 javascript ruby-on-rails twitter oauth omniauth

我正在尝试为我的 RoR 项目实现一个弹出窗口,以实现 Twitter 的登录功能。目前,当您点击登录时,您将被重定向到授权页面,然后一旦您登录,您就会被重定向回来。我希望弹出窗口出现在当前浏览器窗口的顶部,然后在身份验证后关闭。

这是我的 session Controller :

def create
auth_hash = request.env['omniauth.auth']
@user = User.find_by_user_id(auth_hash["uid"])
if @user
    @authorization = @user.authorization
    flash.now[:notice] = "Welcome back #{@user.name}! You have already signed up."
  session[:user_id] = auth_hash["uid"].to_i 
else
    @user = User.new :name => auth_hash["info"]["name"], :user_name => auth_hash["info"]["nickname"], :user_id => auth_hash["uid"], :profile_image_url => auth_hash["info"]["image"].sub("_normal", "")
  @user.build_authorization :secret => auth_hash['credentials']['secret'], :token => auth_hash['credentials']['token']
  @user.build_preference 
    @user.save!
    @user.errors.each do |error|
        puts error
end
    flash.now[:notice] = "Hi #{@user.name}! You've signed up."
  session[:user_id] = auth_hash["uid"].to_i
end
  redirect_to :root
end

def logout
session[:user_id] = nil
redirect_to :root
end

def failure
render :text => "Sorry, but you didn't allow access to our app!"
 end

 def destroy
@user = current_user
if @user
    @user.destroy
    end
redirect_to :root
   end

 end

我四处搜索,发现 Javascript 弹出窗口就是实现这一点的方法,所以我从 StackOverflow 的其他问题之一得到了这个:

Turn omniauth facebook login into a popup

弹出窗口的代码如下:

    function popupCenter(url, width, height, name) {
    var left = (screen.width/2)-(width/2);
    vartop = (screen.height/2)-(height/2);
    return window.open(url, name, "menubar=no,toolbar=no,status=no,width="+width+",height="+height+",toolbar=no,left="+left+",top="+top);
    }

    $("a.popup").click(function(e) {
    popupCenter($(this).attr("href"), $(this).attr("data-width"), $(this).attr("data-height"), "authPopup");
    e.stopPropagation(); return false;
    });

我已经完成了回调 View ,但我不知道该行放在哪里:

     =link_to "Log in with Facebook", omniauth_authorize_path(:user, :facebook), :class => "popup", :"data-width" => 600, :"data-height" => 400

class => 弹出行应该位于我们设置 Twitter 键/ secret 键的位置,但我认为这不是正确的位置( Omniauth - Display facebook connect as popup )。无论如何它都不起作用。 :/

有什么想法吗?

最佳答案

这就是你想要的吗?

应用程序助手:

module ApplicationHelper
  def link_to_login_with(provider, url, html_options = {})
    add_default_class(html_options)
    convert_popup_attributes(html_options)

    link_to t('.login_with_link', provider: provider), url, html_options
  end

  private

  def add_default_class(html_options)
    default_class = "js-popup"

    if html_options.has_key?(:class)
      html_options[:class] << " " << default_class
    else
      html_options[:class] = default_class
    end
  end

  def convert_popup_attributes(html_options)
    width = html_options.delete(:width)
    height = html_options.delete(:height)

    if width && height
      html_options[:data] ||= {}
      html_options[:data].merge!({width: width, height: height})
    end
  end
end

Application.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>Omniauth Popup</title>
  <%= stylesheet_link_tag    'application' %>
  <%= javascript_include_tag 'application' %>
  <%= csrf_meta_tags %>
</head>
<body>
  <header class='main'>
    <nav class='user-nav'>
      <ul>
        <% if current_user %>
          <li>
            <%= link_to current_user do %>
              <%= image_tag current_user.image, class: 'user-pic' if current_user.image %>
              <%= content_tag :span, current_user.name %>
            <% end %>
          </li>
          <li><%= link_to t('.logout_link'), sign_out_path %></li>
        <% else %>
          <li><%= link_to_login_with 'Facebook', '/auth/facebook', { width: '460', height: '460' } %></li>
          <li><%= link_to_login_with 'GitHub', '/auth/github', { width: '1050', height: '700' } %></li>
          <li><%= link_to_login_with 'Google', '/auth/google', { width: '800', height: '470' } %></li>
          <li><%= link_to_login_with 'Twitter', "/auth/twitter?lang=#{I18n.locale}", { width: '660', height: '710' } %></li>
        <% end %>
      </ul>
    </nav>
  </header>

  <div id='js-messages' class='messages'>
    <% flash.each do |type, message| %>
      <span class='message <%= type %>'>
        <%= message %>
      </span>
    <% end %>
  </div>

  <div class='content'>
    <%= yield %>
  </div>
</body>
</html>

应用程序/ Assets /javascripts/login.js

$(document).ready(function() {
    $('.js-popup').click(function() {
        centerPopup($(this).attr('href'), $(this).attr('data-width'), $(this).attr('data-height'));
        return false;
    });
});

function centerPopup(linkUrl, width, height) {
    var sep = (linkUrl.indexOf('?') !== -1) ? '&' : '?',
        url = linkUrl + sep + 'popup=true',
        left = (screen.width - width) / 2 - 16,
        top = (screen.height - height) / 2 - 50,
        windowFeatures = 'menubar=no,toolbar=no,status=no,width=' + width +
            ',height=' + height + ',left=' + left + ',top=' + top;
    return window.open(url, 'authPopup', windowFeatures);
}

Controller

class SessionsController < ApplicationController
  def create
    # Have a look at the info returned by the provider by uncommenting the next line:
    # render text: "<pre>" + env["omniauth.auth"].to_yaml and return
    omniauth = env['omniauth.auth']
    user = User.find_or_create_with_omniauth(omniauth)
    session[:user_id] = user.id
    flash[:notice] = t('controllers.sessions.create', provider: pretty_name(omniauth.provider))
    render_or_redirect
  end

  def failure
    flash[:alert] = t('controllers.sessions.failure', provider: pretty_name(env['omniauth.error.strategy'].name))
    render_or_redirect
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url, notice: t('controllers.sessions.destroy')
  end

  protected

  def render_or_redirect
    page = env['omniauth.origin']
    if env['omniauth.params']['popup']
      @page = page
      render 'callback', layout: false
    else
      redirect_to page
    end
  end

  def pretty_name(provider_name)
    provider_name.titleize
  end
end

app/views/sessions/callback.html.erb

<%= javascript_tag do %>
  window.opener.location = '<%= @page %>';
  window.close();
<% end %>

关于javascript - Twitter 登录的弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29405395/

相关文章:

JavaScript转换数据:image/webp:base64 to png base64 image in safari

javascript - 是否可以将全局变量与 $(this) 一起使用?

twitter - Java 代码中的 OAuth nonce

Javascript:通过变量分配 bool 属性不起作用

javascript - Selenium IDE 的 javascript 中的日期格式类似于 2013 年 9 月 2 日

ruby-on-rails - 运行 Rails 控制台时未初始化的常量测试

ruby-on-rails - 如何将验证错误消息传递给不同 Controller 中的方法?

mysql - Activerecord:这个 MySQL 安全吗?如果没有,我该如何 sanitizer ?

c++ - 用于桌面应用程序的 Twitter API 库?

swift - Twitter 回调 URL