在AdonisJS 4.0中使用Google,Github和Instagram身份验证进行登录

The importance of security and efficient authentication in modern web apps cannot be overly emphasized. From my previous post, Using Facebook/Twitter Authentication in Adonis 4.0. Effective user authentication via Facebook and twitter was discussed and implemented. In this article, we will be talking about authentication using Google, Github and Instagram accounts. An Adonis package Adonis-ally will be employed to achieve this seamlessly.

在现代Web应用程序中,安全性和有效身份验证的重要性不可过分强调。 从我之前的文章“ 在Adonis 4.0中使用Facebook / Twitter身份验证”开始 。 讨论并实现了通过Facebook和Twitter进行的有效用户身份验证。 在本文中,我们将讨论使用Google,Github和Instagram帐户进行身份验证。 我们将采用Adonis软件包Adonis-ally来无缝实现这一目标。

##Adonis-ally The Adonis-ally package is an awesome package that makes it easier to authenticate user via Facebook, Twitter, Google, Linkedin, Instagram, Foursquare and Github. It makes it seamless to implement social authentication and also, more secure.

## Adonis-ally Adonis-ally软件包是一个了不起的软件包,它使通过Facebook,Twitter,Google,Linkedin,Instagram,Foursquare和Github进行身份验证变得更加容易。 它可以无缝地实现社交身份验证,并且更加安全。

##Prerequisites

##先决条件

To get started, you need knowledge of Node.js and JavaScript. The following must be installed on your machine:

首先,您需要了解Node.js和JavaScript。 您的计算机上必须安装以下软件:

  • Node,JS

    节点
  • NPM(Bundled with Node.js installer)

    NPM(与Node.js安装程序捆绑在一起)

##Setup an Adonis Project Open your terminal and type this command.

##设置一个Adonis项目打开您的终端并输入此命令。

# if you don't have Adonis CLI intalled on your machine.
$ npm i -g @adonisjs/cli


# Create a new adonis app and move into the app directory
$ adonis new adonis-social-ii && cd adonis-social-ii

Start the server and test if it's working:

启动服务器并测试其是否正常工作:

$ adonis serve --dev
2017-10-18T09:09:16.649Z - info: serving app on http://127.0.0.1:3333

Open your browser and make a request to http://127.0.0.1:3333. You should see the following.

打开浏览器,并请求http://127.0.0.1:3333 。 您应该看到以下内容。

Let's install adonis-ally package via adonis CLI

让我们通过adonis CLI安装adonis-ally软件包

adonisinstall @adonisjs/ally

Register adonis-ally provider to the application inside start/app.js file.

start/app.js文件中向该应用程序注册adonis-ally提供程序。

const providers = [
  //...
    '@adonisjs/ally/providers/AllyProvider'
  //...
]

数据库设置 ( Database Setup )

I will be using MySQL for this tutorial. Create a database called adonis-social. Get your database's username and password and add it to the .env file in the project's root directory.

我将在本教程中使用MySQL。 创建一个名为adonis-social的数据库。 获取数据库的用户名和密码,并将其添加到项目根目录下的.env文件中。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=adonis-social
DB_USERNAME=root
DB_PASSWORD=adonisjs

迁移与模型 ( Migrations and Models )

Since Adonis installation comes with pre-installed migration and model files for user, We will modify the existing user model and migration file before we migrate it.

由于Adonis安装随附了针对用户的预安装迁移和模型文件,因此我们将在迁移现有用户模型和迁移文件之前对其进行修改。

Go to "database/migrations" directory, delete token.js file then edit `user.js`

转到“数据库/迁移”目录,删除token.js文件,然后编辑` user.js`

###TIMESTAMP_user.js

### TIMESTAMP_user.js

'use strict'

const Schema = use('Schema')

class UserSchema extends Schema {
    up () {
        this.create('users', table => {
            table.increments()
            table.string('name').nullable()
            table.string('avatar').nullable()
            table.string('username', 80).nullable()
            table.string('email', 254).nullable()
            table.string('provider_id').nullable()
            table.string('provider').nullable()
            table.string('password', 60).nullable()
            table.timestamps()
        })
    }

    down () {
        this.drop('users')
    }
}

module.exports = UserSchema

To migrate our table,let's install mysql module

要迁移我们的表,让我们安装mysql模块

$npm install --save mysql

Let's go ahead with the migration.

让我们继续进行迁移。

adonis migration:run

Check your database, users table is created.

检查您的数据库,创建users表。

Let's go to app/Models directory, delete Token.js file then edit User.js file

让我们转到app/Models目录,删除Token.js文件,然后编辑User.js文件

'use strict'

const Model = use('Model')

class User extends Model {
  static boot () {
    super.boot()

    /**
     * A hook to bash the user password before saving
     * it to the database.
     *
     * Look at `app/Models/Hooks/User.js` file to
     * check the hashPassword method
     */
    this.addHook('beforeSave', 'User.hashPassword')
  }

    static get table () {
        return 'users'
    }

    static get primaryKey () {
        return 'id'
    }
}

module.exports = User

##Obtaining Client id and secret. We are going obtain Google/Github/Instagram client id and secret in this section.

##获取客户端ID和机密。 我们将在本节中获取Google / Github / Instagram客户ID和密码。

谷歌 (Google)

  • Visit Google Cloud Console and create new project there

    访问Google Cloud Console并在那里创建新项目
  • Select APIs and services on the sidebar

    在侧边栏中选择API和服务
  • Click on Enable APIs and service

    点击启用API和服务
  • Select Google+ API under social tab and enable it

    在社交标签下选择Google+ API并启用它
  • Next, Click on Credentials tab by the left

    接下来,单击左侧的“凭据”选项卡
  • Select OAuth client id from create Credentials dropdown

    从“创建凭据”下拉列表中选择OAuth客户端ID
  • Select web application, click on configure consent screen

    选择Web应用程序,单击“配置同意”屏幕
  • Fill out the required fields then click on Save

    填写必填字段,然后单击“保存”
  • Select web application, Fill out the required fields then click on Save

    选择Web应用程序,填写必填字段,然后单击“保存”。
  • Name : Adonis login

    姓名:Adonis登录
  • Authorized Javascript origins: http://localhost:3333

    授权JavaScript来源: http:// localhost:3333
  • Authorized redirect URI: http://localhost:3333/authenticated/google

    授权的重定向URI: http:// localhost:3333 / authenticated / google
  • copy the client id and secret into .env

    将客户端ID和密码复制到.env中
GOOGLE_CLIENT_ID=xxxxxxxx
GOOGLE_CLIENT_SECRET=xxxxxxxx

###Github

### Github

GITHUB_CLIENT_ID=xxxxxxxx
GITHUB_CLIENT_SECRET=xxxxxxxx

###Instagram

### Instagram

  • Visit Manage Clients

    访问管理客户
  • click on Register a New Client.

    单击“ 注册新客户”
  • Enter Application Name, description, Contact Email and website URL.

    输入应用程序名称,描述,联系电子邮件和网站URL。
  • For Valid redirect URIs: http://localhost:3333/authenticated/instagram

    对于有效的重定向URI: http://localhost:3333/authenticated/instagram
  • Don't forget to complete captcha challenge.

    不要忘记完成验证码挑战。
  • Copy the client id and secret into .env

    将客户端ID和密码复制到.env中
INSTAGRAM_CLIENT_ID=xxxxxx
INSTAGRAM_CLIENT_SECRET=xxxxxx

Now,we have our client id and secret. Let's update config/service.js file, under ally object, add the following keys if it does not exist.

现在,我们有我们的客户ID和密码。 让我们更新config/service.js文件,在ally对象下,添加以下键(如果不存在)。

[...]
google: {
  clientId: Env.get('GOOGLE_CLIENT_ID'),
  clientSecret: Env.get('GOOGLE_CLIENT_SECRET'),
  redirectUri: `${Env.get('APP_URL')}/authenticated/google`
},
github: {
  clientId: Env.get('GITHUB_CLIENT_ID'),
  clientSecret: Env.get('GITHUB_CLIENT_SECRET'),
  redirectUri: `${Env.get('APP_URL')}/authenticated/github`
},
instagram: {
  clientId: Env.get('INSTAGRAM_CLIENT_ID'),
  clientSecret: Env.get('INSTAGRAM_CLIENT_SECRET'),
  redirectUri: `${Env.get('APP_URL')}/authenticated/instagram`
}
[...]

##Application Views In this section, we will be creating some views for our application. Go to "resource/views" directory then create file called master.edge

##应用程序视图在本节中,我们将为我们的应用程序创建一些视图。 转到“资源/视图”目录,然后创建名为master.edge文件

###master.edge

### master.edge

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="AdonisJs Social">
    <meta name="author" content="">
    <title>AdonisJs Social</title>

    <!-- Fonts -->
    {{ css('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css') }}
    {{ css('https://fonts.googleapis.com/css?family=Lato:100,300,400,700') }}

    <!-- Styles -->
    {{ css('https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap.min.css') }}
    {{ css('https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/5.1.1/bootstrap-social.min.css') }}

    {{ css('style.css') }}
</head>

<body id="app-layout">

<nav class="navbar navbar-expand-md navbar-dark fixed-top">
    <a class="navbar-brand" href="{{ route('welcomePage') }}"><i class="fa fa-cube"></i> Adonis</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarCollapse">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item">
                <a class="nav-link {{ url == route('welcomePage') ? 'active' : '' }}" href="{{ route('welcomePage') }}">HOME</a>
            </li>
        </ul>
        <!-- Right Side Of Navbar -->
        <ul class="navbar-nav navbar-right">
            <!-- Authentication Links -->
            @loggedIn
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    <img src="{{ auth.user.toJSON().avatar }}" style="width: 1.9rem; height: 1.9rem; margin-right: 0.5rem" class="rounded-circle">
                    {{ auth.user.name }} <span class="caret"></span>
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                    <a class="dropdown-item" href="{{ route('logout') }}"><i class="fa fa-btn fa-sign-out"></i> Logout</a>
                </div>
            </li>
            @endloggedIn
        </ul>
    </div>
</nav>

@!section('content')


<!-- JavaScripts -->
{{ script('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js') }}
{{ script('https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js') }}
{{ script('https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/js/bootstrap.min.js') }}

</body>
</html>

Also, replace the content of welcome.edge file

另外,替换welcome.edge文件的内容

欢迎光临 (welcome.edge)

@layout('master')

@section('content')
<div class="container" style="margin-top: 160px">
    <div class="row">
        <div class="col-md-1"></div>
        <div class="col-md-10">
            <div class="card">
                @loggedIn
                <div class="card-header">User Information</div>
                <div class="card-body">
                    <div class="container">
                        <div class="row justify-content-md-center">
                            <div class="col col-md-12">
                                <img src="{{ auth.user.avatar }}">
                                <h2>{{ auth.user.name }}</h2>
                                <h5>{{ auth.user.provider }}</h5>
                            </div>
                        </div>
                    </div>
                    <br>
                </div>
                @else
                <div class="card-header">Authentication</div>
                <div class="card-body">
                    <div class="container">
                        <div class="row justify-content-md-center">
                            <div class="col col-md-6">
                                <a href="{{ route('social.login', {provider: 'google'}) }}"
                                   class="btn btn-block btn-google btn-social">
                                    <i class="fa fa-google-plus"></i>Login with Google
                                </a>
                                <a href="{{ route('social.login', { provider: 'github' }) }}"
                                   class="btn btn-block btn-github btn-social">
                                    <i class="fa fa-github"></i>Login with GitHub
                                </a>
                                <a href="{{ route('social.login', {provider: 'instagram'}) }}"
                                   class="btn btn-block btn-instagram btn-social">
                                    <i class="fa fa-instagram"></i>Login with Instagram
                                </a>
                            </div>
                        </div>
                    </div>
                    <br>
                </div>
                @endloggedIn
            </div>
        </div>
    </div>
</div>
@endsection

Refresh your browser, your home page should look like this.

刷新浏览器,您的主页应如下所示。

##Routes

##路线

Time to take care of our application's route. Go to "start/routes.js" and replace the content with:

是时候照顾我们的应用程序的路线了。 转到“ start / routes.js”,并将内容替换为:

###routes.js

### routes.js

'use strict'

const Route = use('Route')

Route.on('/').render('welcome')
Route.get('/logout', 'AuthController.logout').as('logout')
Route.get('/auth/:provider', 'AuthController.redirectToProvider').as('social.login')
Route.get('/authenticated/:provider', 'AuthController.handleProviderCallback').as('social.login.callback')

Three routes was added to the existing ones. One for redirecting the user to the OAuth provider(Google, Github and Instagram in our case), another one for receiving the callback from the provider after authentication and last one for logout.

现有路线中增加了三条路线。 一个用于将用户重定向到OAuth提供程序(在本例中为Google,Github和Instagram),另一个用于在身份验证后接收来自提供程序的回调,最后一个用于注销。

##Controllers Let's create a controller for the application. we are going to call it AuthController. Run the below command to create this controller.

## Controllers让我们为应用程序创建一个控制器。 我们将其称为AuthController 。 运行以下命令创建此控制器。

adonis make:controller AuthController

It will ask you Generating a controller for ? select Http Request

它将要求您生成控制器用于? 选择Http Request

Go to app/Controllers/Http/ directory, you will discover a controller called AuthController.js has been created.

转到app/Controllers/Http/目录,您将发现一个名为AuthController.js的控制器已创建。

###AuthController.js

### AuthController.js

'use strict'

const User = use('App/Models/User')

class AuthController {

    async redirectToProvider ({ally, params}) {
        await ally.driver(params.provider).redirect()
    }

    async handleProviderCallback ({params, ally, auth, response}) {
        const provider = params.provider
        try {
            const userData = await ally.driver(params.provider).getUser()

            const authUser = await User.query().where({
                'provider': provider,
                'provider_id': userData.getId()
            }).first()
            if (!(authUser === null)) {
                await auth.loginViaId(authUser.id)
                return response.redirect('/')
            }

            const user = new User()
            user.name = userData.getName()
            user.username = userData.getNickname()
            user.email = userData.getEmail()
            user.provider_id = userData.getId()
            user.avatar = userData.getAvatar()
            user.provider = provider

            await user.save()

            await auth.loginViaId(user.id)
            return response.redirect('/')
        } catch (e) {
            console.log(e)
            response.redirect('/auth/' + provider)
        }
    }

    async logout ({auth, response}) {
        await auth.logout()
        response.redirect('/')

    }
}
module.exports = AuthController

Before we test our code, let's talk about the functions in the controller.

在测试代​​码之前,让我们谈谈控制器中的功能。

  • redirectToProvider handles redirecting of the user to the OAuth provider(Google, Github and Instagram).

    redirectToProvider处理用户到OAuth提供程序(Google,Github和Instagram)的重定向。

  • handleProviderCallback handles retrieve the user's information from the provider(Google, Github and Instagram). In this method, we checked if the user already exist in the database. If so,we return the user's information. Otherwise, create a new user. This concept prevent user account to be created twice.

    Note: when you test the application with google chrome,it might not log you in because of many re-direct that occurs in the background.To fix this, you have to set sameSite: false inside config/session.js. But for other browsers, you should be fine.

    handleProviderCallback句柄从提供者(Google,Github和Instagram)检索用户的信息。 在这种方法中,我们检查用户是否已存在于数据库中。 如果是这样,我们将返回用户的信息。 否则,请创建一个新用户。 此概念可防止两次创建用户帐户。

    注意:当您使用google chrome测试应用程序时,由于在后台进行许多sameSite: false ,它可能无法登录。要解决此问题,必须在config/session.js设置sameSite: false 。 但是对于其他浏览器,您应该没问题。

The view when i login via google, github and instagram.

我通过Google,github和instagram登录时的视图。

github
Github Google
instagram
Instagram

Github

谷歌
谷歌 Instagram的

结论 ( Conclusion )

Your application now provide users the option of using different social login providers to securely gain access to your service. No restrictions. No boundaries.

现在,您的应用程序为用户提供了使用其他社交登录提供程序的选项,以安全地访问您的服务。 无限制。 没有界限。

If you have any questions or observations, feel free to drop it in the comments section below. I would be happy to respond to you.

如果您有任何疑问或意见,请随时将其放在下面的评论部分。 我很高兴回应您。

翻译自: https://scotch.io/tutorials/using-google-github-and-instagram-authentication-for-login-in-adonisjs-40

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值