钉钉二维码登录过程

钉钉扫码登录实现过程

步骤如下:

1.设计好需要放钉钉扫码的页面

2.在钉钉上注册获取到生成相关二维码的页面链接URL,即请求相应接口获取到该页面链接:
<https://service.100tal.com/sso/login/236049354?uuid=d258113c-c39d-11e8-b304-5afc69781f14 >
注意: 这里的链接是由后端将钉钉返回的一个iframe标签窗口生成之后返回的,有可能后端会直接返回一个iframe标签,如果是直接跳转二维码可以不用生成链接,点击iframe可以直接跳转,如果生成二维码,则需要后端将iframe嵌套在某个URL页面里并返回改URL,然后再生成二维码

在这里插入图片描述
在这里插入图片描述
3.获取到链接后,去生成二维码,生成二维码需要安装qrcode插件,可以通过在命令行下载插件:
cnpm install -g qrcode
cnpm install -g jsonp

qrcode插件是用于生成二维码的,jsonp用来在页面内跨域请求
在这里插入图片描述安装后会在package.json文件里出现对应插件

4.在组件里引入qrcodejs文件,然后在对应二维码代码中写qrcode组件,来生成二维码

<div id="qrcode" ref="qrcode" v-show="!isScanSuccess"></div>
import QRCode from 'qrcodejs2'

登录案例:

<div v-else>
    <div class="qrcode-portion">
      <div class="scan-success" v-show="isScanSuccess">
        <p>扫码成功</p>
        <p>请在手机钉钉中点击登录</p>
      </div>
      <div id="qrcode" ref="qrcode" v-show="!isScanSuccess"></div>
    </div>
    <div class="dd-login">请用钉钉扫码登录</div>
</div>

import QRCode from 'qrcodejs2'

生成二维码:

setQrcode () {
   if (this.tokenTag) {
    window.clearInterval(this.timer)
    return
  }
  let qrcode = new QRCode('qrcode', {
    width: 188,
    height: 188,
    text: this.qrcodeUrl, // 二维码地址
  })
}

5.在service文件夹下写一个用于jsonp跨域的文件,在main.js里因为service。
注意:这里http.js跨域文件会单独发表一个博客文件
在这里插入图片描述
6.现在二维码已经显示了,然后使用后台返回的uuid去调用jsonp跨域请求钉钉,请求后会获取到一个token值,来判断你当前是否可以进行钉钉登录,主要是用来判断你是否在该公司名下,是否可以成功登录,即token为true,当token为true时调用登录接口和登录成功接口

 waitSCan () {
  const url = 'https://api.service.100tal.com/sso/qrcode/status'
  this.$http.jsonp(url, {
                uuid: this.uuid || ''
            })
            .then(res => {
                if (res) {
                    this.getDingdingLogin(res)
                } else {
                    console.log('jsonp请求失败')
                }
            })
            .catch(err => {
                window.clearInterval(this.qrcodeTimer) // 清除计时器
            })
}

7.由于二维码会失效,所以需要1秒更新刷新一次二维码,保证二维码时刻有效

写到这里基本上就大功告成了,下面我会贴出钉钉二维码登录时的整体文件代码,使用时可以参考:

<template>
    <div class="login">
       <div class="login_form">
       	<img src="../../assets/img/logo-login.png" class='login_logo'/>
      	<div class="form_t">
      		 <div class="login-tab clearfix">
            <p :class="[tabTag == 'qrcode'? 'active' : '']" @click="clickTab('qrcode');showQrcode()">二维码登录</p>
            <p :class="[tabTag == 'email'? 'active' : '']" @click="clickTab('email')">邮箱登录</p>
          </div>
          <div v-if="tabTag == 'email'">
      		<div class="user-name common-div">
                <input type="text" name="userEmail" v-model="userEmail" placeholder="请输入邮箱地址"/>
                <img src="../../assets/img/user.svg"/>
          </div>
          <div class="user-pasw common-div">
                <input type="password" name="password" v-model="password" placeholder="请输入密码" @focus="cookiePassword" @keyup.enter="_login"/>
                <img src="../../assets/img/lock.svg"/>
          </div>
          <div class="login-btn" @click="_login">登录</div>
          <div class="footer clearfix">
      		<div class="remeber clearfix">
      		   <span class="checkbox" @click='remeber'><i v-if='checked' class='fa fa-check'></i></span>
      		   <label>记住密码</label>
      		</div>
      		<a class="forget" @click='showModal=true'>忘记用户名或密码?</a>
      	</div>
       </div>
       <div v-else>
            <div class="qrcode-portion">
              <div class="scan-success" v-show="isScanSuccess">
                <p>扫码成功</p>
                <p>请在手机钉钉中点击登录</p>
              </div>
              <div id="qrcode" ref="qrcode" v-show="!isScanSuccess"></div>
            </div>
            <div class="dd-login">请用钉钉扫码登录</div>
          </div>
        </div>
       </div>
       <modal :show.sync="showModal" class="modal-lg category_modal" :clean-data="cleanData" :click-confirm="clickConfirm">
         	<div slot="header">
                                    找回密码
              <span class="ico-close" @click='cleanData'>x</span>
            </div>
            <div slot="body" class="form-horizontal email">
            	<p>请输入您的100tal邮箱地址,然后前往重置密码</p>
            	<input type="text"  id="" value="" v-model='email' placeholder="请输入邮箱"/>
            </div>
       </modal>
    </div>
</template>

<script>
/* eslint-disable */
import { mapActions } from 'vuex'
import modal from '../../components/util/Modal'
import QRCode from 'qrcodejs2'
import { setTimeout } from 'timers';
export default {
	data () {
		return {
			userEmail: '',
			password: '',
			showModal: false,
			email: '',
			checked: false,
      tabTag: 'qrcode',
      qrcodeUrl: '',
      uuid: '',
      scanOK: false,     // 等待扫描结果
      qrcodeTimer: null,
      timer: null,
      passStage: null,
      tokenTag: false,
      isScanSuccess: false
		}
	},
  methods: {
  	...mapActions({
      login: 'login',
      getQrcode: 'getQrcode', //获取钉钉登录二维码
      dingdingLogin: 'dingdingLogin', //钉钉登录
      forgetPassword: 'forgetPassword', // 忘记密码或用户
      setUserInfo: 'setUserInfo', // 存储用户信息
			alertMsg: 'alertMsg'
    }),
    remeber () {
      this.checked = !this.checked
    },
    setCookie(name, value, iDay) {
	    var oDate=new Date()
	    oDate.setDate(oDate.getDate()+iDay)
	    document.cookie=name+'='+encodeURIComponent(value)+';expires='+oDate
	  },
	  getCookie(name){
	    var arr = document.cookie.split('; ')
	    var i = 0
	    for(i=0; i<arr.length; i++){
				var arr2 = arr[i].split('=')
				if(arr2[0]==name){
					var getC = decodeURIComponent(arr2[1])
					return getC
				}
	    }
	    return ''
    },
    cookiePassword() {
      this.password = this.getCookie(this.userEmail)
    },
  	_login () {
      if (!this.userEmail || !this.password) {
      	this.alertMsg("请填写完整信息")
      	return
      }
      const params = {
      	email: this.userEmail,
      	password: this.password
      }
      this.setCookie('userName', this.userEmail)
      if (this.checked) {
      	this.setCookie(this.userEmail, this.password,999);
			}
			this.login({
				params: params,
				setData: this.loginSuccess
			})
		},
		loginSuccess (data) {
      this.tokenTag = true
      this.isScanSuccess = false
      window.clearInterval(this.timer)
      window.clearInterval(this.qrcodeTimer)
			this.setUserInfo(data) // 存储用户信息
			this.$router.replace('/handout')
    },
    showQrcode () {
      if (this.tokenTag) return
      let that = this
      window.clearInterval(this.timer)
      this.getQrcode({
        params: '',
        setData: this.setQrcodeToken
      })
      window.clearTimeout(this.passStage)
      this.timer = setInterval(() => {
        if (!that.$refs.qrcode) return
        that.$refs.qrcode.innerHTML = ''
        this.showQrcode()
      }, 60000)
    },
    setQrcode () {
       if (this.tokenTag) {
        window.clearInterval(this.timer)
        return
      }
      let qrcode = new QRCode('qrcode', {
        width: 188,
        height: 188,
        text: this.qrcodeUrl, // 二维码地址
      })
    },
    setQrcodeToken (data) {
      window.clearInterval(this.qrcodeTimer) // 清除计时器
      let that = this
      let nextcall_eg = data.nextcall_eg
      this.qrcodeUrl = data.qrcode
      this.uuid = data.uuid
      this.setQrcode()
      this.waitSCan()
      this.qrcodeTimer = setInterval(() => { this.waitSCan() }, 1000)
    },
    waitSCan () {
      const url = 'https://api.service.100tal.com/sso/qrcode/status'
      this.$http.jsonp(url, {
                    uuid: this.uuid || ''
                })
                .then(res => {
                    if (res) {
                        this.getDingdingLogin(res)
                    } else {
                        console.log('jsonp请求失败')
                    }
                })
                .catch(err => {
                    window.clearInterval(this.qrcodeTimer) // 清除计时器
                })
    },
    getDingdingLogin (data) {
      let that = this
      if (data.stage == 9 && data.token){
        this.tokenTag = true
         const obj = {
                        "token": data.token
                    }
        this.dingdingLogin({
          params: obj,
          setData: this.loginSuccess
        })
      }
      if (data && data.errcode === 0 && data.stage === 1) {
        this.isScanSuccess = true
        this.passStage = setTimeout(() => {
          if (!that.isScanSuccess) return
          if (that.$refs.qrcode) that.$refs.qrcode.innerHTML = ''
          that.showQrcode()
          that.isScanSuccess = false
        }, 61000) // 扫码未确认超出1分一秒时跳转二维码显示
     }
    },
  	cleanData () {
  		this.showModal = false
  		this.email = ''
  	},
  	clickConfirm () {
  		if (!this.email) {
  			this.alertMsg('邮箱不可以为空')
  			return
			}
			this.forgetPassword({
				params: { email: this.email },
				setData: () => {
					this.alertMsg('发送成功,请前往邮箱查看'),
					this.showModal = false
					this.email = '';
				},
				erroCb: () => {
					this.showModal = false
					this.email = ''
				}
			})
  	},
    clickTab (tabType) {
      this.tabTag = tabType
    }
  },
  mounted () {
    this.showQrcode()
    this.userEmail = this.getCookie('userName')
    localStorage.removeItem('rembasicInfo')
    if (this.userEmail) this.password = this.getCookie(this.userEmail)
  },
  components: {
  	modal
  }
}

</script>

<style scoped>
  .login{
  min-height: 450px;
  width: 312px;
	position: absolute;
	top:50%;
	left: 50%;
  margin-left: -156px;
  margin-top: 129px;
  }
  .form_t{
	height: 320px;
	background: rgba(0,0,0,0.30);
  border-radius: 6px;
  padding: 40px;
  }
  .form_t div {
     width: 232px;
     height: 36px;
     line-height: 36px;
     border-radius: 3px;
  }
  .form_t .login-tab {
    height: 34px;
    background:rgba(255,255,255,0);
    border:1px solid rgba(255,255,255,0.24);
    border-radius: 18px;
    color:rgba(255,255,255,1);
    margin-bottom: 36px;
    font-family:PingFangSC-Regular;
  }
  .form_t .login-tab .active {
    background: rgba(255,255,255,0.23);
  }
  .login-tab p {
    width: 115px;
    height: inherit;
    float: left;
    cursor: pointer;
  }
  .login-tab p:first-child {
    border-right: 1px solid rgba(255,255,255,0.24);
    border-radius:18px 0px 0px 18px;
  }
  .login-tab p:last-child {
    width: 116px;
    border-radius:0 18px 18px 0;
  }
  .txt{
	height:112px;
	line-height: 112px;
	font-size: 18px;
    color: #fff;
   }
  .common-div{
  	position:relative;
  }
  .common-div input{
  	width: calc(100% - 9px);
    height: calc(100% - 2px);
  	font-size: 14px;
    padding-left:8px ;
    color: #fff;
  	border:0;
  	border-radius: 3px;
  	background-color: rgba(0,0,0,0.24);
  }
  .common-div input::placeholder {
    color: #fff;
  }
  .user-pasw {
    margin: 24px 0 48px 0;
  }
  .common-div img{
  	display: block;
  	width: 14px;
    height: 14px;
    position: absolute;
    right: 10px;
    top: 11px;
  }
  .footer {
    position: relative;
  }
  .form_t .remeber{
    float: left;
    width: 68px;
    color: #fff;
    font-size: 12px;
    height: 12px;
    line-height: 14px;
    margin-top: 12px;
  }
  .checkbox{
  	float: left;
  	width: 12px;
    height: 12px;
  	border: 1px solid #BDBDBD;
  	background: #fff;
    border-radius: 3px;
    margin-right: 5px;
  }
  .login-btn{
  line-height: 40px;
  font-size: 20px;
  color: #fff;
  height:40px;
  background:rgba(245,166,35,0.5);
  border-radius:3px;
  border:1px solid rgba(245,166,35,0.8);
  cursor: pointer;
  font-family:PingFangSC-Regular;
  }
  .login_logo{
  	margin-bottom: 24px;
  	width: 318px;
  	height: 42px;
  }
  .forget{
  float: right;
	color: #fff;
	cursor: pointer;
	border-bottom: 1px solid #fff;
	height: 24px;
  font-size: 12px;
  }
  .email p{
  	padding-top:50px ;
  	width: 400px;
  	height: 40px;
  	line-height: 40px;
  	text-align: center;
  	font-size:16px ;
  	font-weight: 700;
  }
  .email input{
  	display: block;
  	width: 350px;
  	height: 40px;
    line-height: 40px;
    padding-left: 14px;
    border: 1px solid #979797;
    box-shadow: inset 0 1px 3px 0 rgba(0,0,0,.5);
    border-radius: 5px;
    color: #949494;
    margin-top:20px;
    margin-left: 24px;
  }
  .fa-check{
  	color: #000;
  }
    .form_t .qrcode-portion {
    margin-top: 42px;
    width: calc(100% - 32px);
    height: 200px;
    background:rgba(255,255,255,0.23);
    box-shadow:0px 0px 1px 0px rgba(0,0,0,0.5),0px 0px 1px 0px rgba(255,255,255,0.5);
    border-radius:6px;
    padding: 16px;
  }
  .form_t .qrcode-portion .scan-success{
    width: 100%;
    height: auto;
    margin-top: 61px;
    color: rgba(0,0,0,.5);
  }
  .scan-success p:first-child{
    color: #48c55f;
    font-size: 20px;
    font-weight: 500;
  }
  .form_t .dd-login {
    color:rgba(255,255,255,1);
    margin-top: 12px;
    height: 14px;
    line-height: 14px;
  }
  #qrcode {
    display: inline-block;
    width: calc(100% - 12px);
    height: calc(100% - 12px);
    padding: 6px;
    background-color: #fff;
  }

</style>

猜你喜欢

转载自blog.csdn.net/qq_32885597/article/details/88063651
今日推荐