├── .gitignore ├── .travis.yml ├── README.md ├── example ├── facebook_oauth_handler.js └── facebook_server.js └── lib ├── http_request.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | .env 29 | 30 | /_build 31 | /.elixir_ls 32 | /deps -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.2.2" 4 | before_install: 5 | - pip install --user codecov 6 | after_success: 7 | - codecov --file coverage/lcov.info --disable search 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # `elixir-auth-facebook` Comming Soon! See: [`#21`](https://github.com/dwyl/elixir-auth-facebook/issues/21) 4 | 5 | ![img](http://i.stack.imgur.com/pZzc4.png) 6 | 7 | _Easily_ add `Facebook` login to your `Elixir` / `Phoenix` Apps 8 | with step-by-step **_detailed_ documentation**. 9 | 10 | ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/dwyl/auth/Elixir%20CI?label=build&style=flat-square) 11 | [![codecov.io](https://img.shields.io/codecov/c/github/dwyl/auth/master.svg?style=flat-square)](http://codecov.io/github/dwyl/auth?branch=master) 12 | [![Hex.pm](https://img.shields.io/hexpm/v/auth?color=brightgreen&style=flat-square)](https://hex.pm/packages/auth) 13 | [![Libraries.io dependency status](https://img.shields.io/librariesio/release/hex/auth?logoColor=brightgreen&style=flat-square)](https://libraries.io/hex/auth) 14 | [![docs](https://img.shields.io/badge/docs-maintained-brightgreen?style=flat-square)](https://hexdocs.pm/auth/api-reference.html) 15 | [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/auth/issues) 16 | [![HitCount](http://hits.dwyl.com/dwyl/elixir-auth-facebook.svg)](http://hits.dwyl.com/dwyl/elixir-auth-facebook) 17 | 18 |
19 | 20 | ## Why? 21 | 22 | Facebook authentication is used **_everywhere_**! 23 | We wanted to create a reusable `Elixir` package 24 | with beginner-friednly instructions and readable code. 25 | 26 | ## What? 27 | 28 | A simple and easy-to-use `Elixir` package 29 | that gives you 30 | **Facebook `OAuth` Authentication** 31 | in a few steps. 32 | 33 | > If you're new to `Elixir`, 34 | > please see: [dwyl/**learn-elixir**](https://github.com/dwyl/learn-hapi) 35 | 36 | ## How? 37 | 38 |
39 | 40 | # ⚠️ WARNING: This is out-of-date see: [`#21`](https://github.com/dwyl/elixir-auth-facebook/issues/21) 41 | 42 |
43 | 44 | These instructions will guide you through setup in 6 simple steps 45 | by the end you will have 46 | **login with `Facebook`** 47 | working in your App. 48 | No prior experience/knowledge 49 | is expected/required. 50 | 51 | > **Note**: if you get stuck, 52 | > please let us know by opening an issue! 53 | 54 | ### Step 1: Upgrade your personal Facebook account to a developer account 55 | 56 | Go to developers.facebook.com/apps 57 | 58 | ![upgrade-account](https://files.gitter.im/jackcarlisle/hapi-auth-facebook/KNoV/facebook1.png) 59 | 60 | ...after logging in to your facebook account, you can 'Register Now' for a developer account. 61 | 62 | ### Step 2: Select what platform your app is on 63 | 64 | ![makeapp](https://files.gitter.im/jackcarlisle/hapi-auth-facebook/YOYX/facebook3.png) 65 | 66 | ### Step 3: Skip to create an App 67 | 68 | On this page, you can click the button in the top right to quickly access your app's id. 69 | 70 | ![skip](https://files.gitter.im/jackcarlisle/hapi-auth-facebook/YOYX/facebook4.png) 71 | 72 | ### Step 4: Create App 73 | 74 | Here you can specify your app's name (doesn't **_have_** to be unique!) 75 | 76 | ![nameapp](https://files.gitter.im/jackcarlisle/hapi-auth-facebook/YOYX/facebook5.png) 77 | 78 | **Note**: Copy the App ID and the Secret into your `.env` file. 79 | 80 | ### Step 5: Specify Redirect URI 81 | 82 | Inside the facebook app's **advanced** settings, specify the redirect URI near the _bottom_ of the page: 83 | 84 | ![redirecturi](https://files.gitter.im/jackcarlisle/hapi-auth-facebook/QG8M/Screen-Shot-2015-11-27-at-12.21.57.png) 85 | 86 | **Note**: the redirect URI has to be an _absolute_ URI - make sure you include the `http://` prefix. 87 | 88 | ### Step 6: Make a request in your `Elixir` / `Phoenix` server 89 | 90 | In your `Phoenix` server, make a request to the following url specifying your individual `app-id` and `redirect-uri` 91 | 92 | ![facebookRequest](https://files.gitter.im/jackcarlisle/hapi-auth-facebook/fkmD/Screenshot-from-2015-11-27-12_21_22.png) 93 | 94 | -------------------------------------------------------------------------------- /example/facebook_oauth_handler.js: -------------------------------------------------------------------------------- 1 | var authHandler = function (request, reply, accessToken) { 2 | reply("Your token: " + accessToken); 3 | }; 4 | 5 | module.exports = authHandler; 6 | -------------------------------------------------------------------------------- /example/facebook_server.js: -------------------------------------------------------------------------------- 1 | var Hapi = require("hapi"); 2 | var server = new Hapi.Server(); 3 | var assert = require("assert"); 4 | 5 | var facebookAuth = require("../lib/index.js"); 6 | 7 | server.connection({ 8 | host: "0.0.0.0", 9 | port: Number(process.env.PORT), 10 | }); 11 | 12 | var facebookAuthRequestUrl = "/authfacebook"; 13 | 14 | server.register( 15 | { 16 | register: facebookAuth, 17 | options: { 18 | handler: require("./facebook_oauth_handler"), 19 | redirectUri: "/facebooklogin", 20 | tokenRequestPath: facebookAuthRequestUrl, 21 | }, 22 | }, 23 | function (err) { 24 | assert(!err, "failed to load plugin"); 25 | } 26 | ); 27 | 28 | var createLoginButton = function () { 29 | return ( 30 | '' 33 | ); 34 | }; 35 | 36 | server.route({ 37 | path: "/facebook", 38 | method: "GET", 39 | handler: function (request, reply) { 40 | reply(createLoginButton()); 41 | }, 42 | }); 43 | 44 | server.start(function () { 45 | console.log("Server listening on " + server.info.uri); 46 | }); 47 | 48 | module.exports = server; 49 | -------------------------------------------------------------------------------- /lib/http_request.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dwyl/elixir-auth-facebook/050cd9410ae02a23d4bd0447b3d9dd3fee449084/lib/http_request.js -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var env = require("env2")(".env"); 2 | var querystring = require("querystring"); 3 | var https = require("https"); 4 | 5 | var createAccessTokenQuery = function (request, server, options) { 6 | var query = querystring.stringify({ 7 | client_id: process.env.FACEBOOK_APP_ID, 8 | redirect_uri: server.info.uri + options.redirectUri, 9 | client_secret: process.env.FACEBOOK_APP_SECRET, 10 | code: request.query.code, 11 | }); 12 | return query; 13 | }; 14 | 15 | var createAccessTokenReqestOpts = function (request, server, options) { 16 | var accessTokenQuery = createAccessTokenQuery(request, server, options); 17 | return { 18 | hostname: "graph.facebook.com", 19 | path: "/v2.3/oauth/access_token?" + accessTokenQuery, 20 | method: "GET", 21 | }; 22 | }; 23 | 24 | var getBody = function (response, callback) { 25 | var body = ""; 26 | response.on("data", function (chunk) { 27 | body += chunk; 28 | }); 29 | response.on("end", function () { 30 | callback(body); 31 | }); 32 | }; 33 | 34 | var httpsRequest = function (options, callback) { 35 | var request = https.request(options, function (response) { 36 | getBody(response, callback); 37 | }); 38 | request.end(); 39 | }; 40 | 41 | var redirectHandler = function (request, reply, server, options) { 42 | var requestOpts = createAccessTokenReqestOpts(request, server, options); 43 | httpsRequest(requestOpts, function (accessTokenData) { 44 | var token = JSON.parse(accessTokenData).access_token; 45 | options.handler(request, reply, token); 46 | }); 47 | }; 48 | 49 | function createFacebookAuthReqUrl(server, redirectUri) { 50 | host = "https://www.facebook.com"; 51 | path = 52 | "/dialog/oauth?" + 53 | querystring.stringify({ 54 | client_id: process.env.FACEBOOK_APP_ID, 55 | redirect_uri: server.info.uri + redirectUri, 56 | }); 57 | return host + path; 58 | } 59 | 60 | var authReqHandler = function (request, reply, server, options) { 61 | reply.redirect(createFacebookAuthReqUrl(server, options.redirectUri)); 62 | }; 63 | 64 | exports.register = function (server, options, next) { 65 | server.route([ 66 | { 67 | method: "GET", 68 | path: options.tokenRequestPath, 69 | handler: function (request, reply) { 70 | authReqHandler(request, reply, server, options); 71 | }, 72 | }, 73 | { 74 | method: "GET", 75 | path: options.redirectUri, 76 | handler: function (request, reply) { 77 | redirectHandler(request, reply, server, options); 78 | }, 79 | }, 80 | ]); 81 | next(); 82 | }; 83 | 84 | exports.register.attributes = { 85 | name: "hapi-auth-facebook", 86 | }; 87 | --------------------------------------------------------------------------------