Skip to content

Everyauth integration example

erundook edited this page Nov 10, 2012 · 2 revisions

app/config/server/initializers/everyauth.coffee

everyauth = require 'everyauth'
findOrCreateUser = (session, provider, meta, context) ->
  promise = context.Promise()
  uid = switch provider
    when 'vkontakte' then meta.uid
    when 'facebook' then meta.id
  App.User.where(social_id: uid).first (err, rec) ->
    return promise.fail(err) if err
    if rec
      session.user = rec
      session.save()
      promise.fulfill uid
    else
      App.User.createFromSocial(session, provider, uid, promise)
  return promise

everyauth.everymodule.logoutRedirectPath '/users'
everyauth.everymodule.findUserById (userId, cb) ->
  app.get('models').User.findById userId, cb
everyauth.vkontakte
  .appId('12345678')
  .appSecret('abcdefghijklmn')
  .scope('notify,wall,friends')
  .redirectPath('/users')
  .findOrCreateUser (session, token, tokenExtra, vkUser) ->
    findOrCreateUser(session, 'vkontakte', vkUser, @)

everyauth.facebook
  .appId('123456789012345')
  .appSecret('abcdefghijklmnabcdefghijklmn')
  .redirectPath('/users')
  .findOrCreateUser (session, token, tokenExtra, fbUser) ->
    findOrCreateUser(session, 'facebook', fbUser, @)

app/config/server/bootstrap.coffee

comment out cookie domain setting & add everyauth middleware before Tower.MiddlewareRouter

everyauth = require 'everyauth'
App.configure ->
  @use 'favicon', Tower.publicPath + '/favicon.png'
  @use 'static',  Tower.publicPath, maxAge: Tower.publicCacheDuration
  @use 'logger'
  @use 'query'
  @use 'cookieParser', Tower.config.session.key
  @use 'session', secret: Tower.config.session.secret #, cookie: {domain: Tower.config.session.cookie.domain}
  @use 'bodyParser', uploadDir: './public/uploads'
  #@use 'csrf'
  @use 'methodOverride', '_method'
  # don't expose your platform to hackers
  @use (request, response, next) ->
    response.removeHeader('X-Powered-By')
    next()
  @use Tower.MiddlewareAgent
  @use Tower.MiddlewareLocation
  # if Tower.httpCredentials && Tower.branch != 'development'
  #   @use 'basicAuth', Tower.httpCredentials.username, Tower.httpCredentials.password
  @use everyauth.middleware(App)
  @use Tower.MiddlewareRouter

  # For "web sockets" on heroku:
  # App.io.configure ->
  #   App.io.set('transports', ['xhr-polling'])

app/models/shared/user.coffee

class App.User extends Tower.Model
  @field 'id',        type: 'Id'
  @field 'social',    type: 'String'
  @field 'social_id', type: 'String'

  @createFromSocial: (session, provider, uid, promise) ->
    @.create
      social: provider
      social_id: uid

    session.user = @
    session.save()
    promise.fulfill uid

app/templates/shared/layout/_navigation.coffee

add some links to log in and out

a class: 'btn btn-navbar', data: {toggle: 'collapse', target: '.nav-collapse'}, ->
  span class: 'icon-bar'
  span class: 'icon-bar'
  span class: 'icon-bar'
a '{{action showRoot href=true}}', class: 'brand', -> t('title')
div class: 'nav-collapse', ->
  ul class: 'nav', ->
    li '{{bindAttr class="App.UserController.isActive:active"}}', ->
      a '{{action indexUser href=true}}', t('links.users')
    li -> a href: '/auth/vkontakte', 'VK'
    li -> a href: '/auth/facebook', 'FB'
    li -> a href: '/logout', 'Log out'
  ul class: 'nav pull-right', ->
    li class: 'dropdown', ->
      linkTo t('links.docs'), '#', class: 'dropdown-toggle', 'data-toggle': 'dropdown', ->
        b class: 'caret'
      ul class: 'dropdown-menu', ->
        li ->
          linkTo 'Tower.js', 'https://github.com/viatropos/tower/wiki'
Clone this wiki locally