keycloak单点登录(浙政钉2.0扫码、手机号验证码登录)

写在前面:本篇博客只针对前端代码实现,keycloak配置什么的,自己和后端或者运维联调吧。说实在的,因为不熟悉keycloak代码的逻辑,再加上时间紧,所以搞了一些很多骚操作。
登录这些前端代码是写在keycloak项目里的,文件是.ftl,还好政府项目没有对UI有什么很高的要求。扫码登录和手机号验证码,成功之后是跳转到Vue项目里的。
@TOC

浙政钉扫码登录

扫码登录:

在这里插入图片描述
专有钉钉扫码登陆流程
我这里采用的时第二种实现方式,嵌入iframe,但是这样有个弊端,开发时由于跨域,无法改二维码的样式。
在这里插入图片描述

template_login.ftl
<div id="login_container">
	<!--这个时关联form表单的代码 具体代码在sms-captcha-login.ftl-->
                        <#nested "form">
                        <div class="tabContentCode active" id="frame">
                        	<!--这段代码没啥主要是遮住二维码上面的字,就是一个白色的背景区域-->
                            <div class="cover coverbg" id="cover"></div>
                            <iframe name="my-iframe" id="myFrame" 
                            src="" 
                            frameborder="0" 
                            width="310" height="310" scrolling="no"></iframe>
                        </div>
                    </div>
<#import "template_login.ftl" as layout>
<@layout.registrationLayout displayInfo=social.displayInfo displayWide=(realm.password && social.providers??); section>
    <#if realm.password && social.providers??>
    	<!--首先循环p-->
		<#list social.providers as p>
		<!--当p.providerId == "dgwork"做判断操作,但是循环了三次,没有找到具体原因,所以就做了一下操作只取第一次循环的数据,之后的全部返回-->
        <#if p.providerId == "dgwork">
			<script defer="defer">
			var num = window.localStorage.getItem('first');
			console.log("************"+num);
			if(!num){
				num = 0
				window.localStorage.setItem('first', num);
			}	
			if(num==0){
				console.log("*****11111*******");
				window.addEventListener('message', function(event) {
				  var origin = event.origin;
				  //https://openplatform-portal.dg-work.cn/portal/#/helpdoc?docKey=kfzn&slug=engk1k  下面的origin时这个地址里的各环境域名/登录域名,线上环境是login-pro.ding.zj.gov.cn
				  
				  if (origin == "https://login.dg-work.cn") {
					var loginTmpCode = event.data; 
					//取网址里的参数开始
					var search = http_url.substring(1)
					if (!search && location.href.lastIndexOf('?') > -1) {
					  search = location.href.substring(location.href.lastIndexOf('?') + 1)
					}
					var obj = {}
					if (search.length > 0) {
					  var arr = [], item
					  arr = search.split('&')
					  for (var i = arr.length; --i >= 0;) {
						item = arr[i].split('=')
						obj[item[0]] = item[1]
					  }
					}
					//取网址里的参数结束主要取往里的回调地址redirect_uri,code和state是监听返回的也是必须的
					var new_uri= decodeURIComponent(obj.redirect_uri) + '?code='+loginTmpCode.code+'&state='+loginTmpCode.state;
					try {
						//跳到新的回调地址去,也就是页面的跳转
					  top.location.assign(new_uri);
					} catch (e) {
					  top.location.href=new_uri;
					}
				  }
				})
				var http_url='';
				//htmlUtil时引入 的文件,主要用来对网址解码用的,可以自定义
				var login_url=htmlUtil.decode("${p.loginUrl}");
				
				if("${p.providerId}" == 'dgwork'){
					//这个玩意也是引入的原生js文件,可以用ajax试试
					ajaxHandler.Ajax({
					url: login_url,
					type: "get",
					success: function (result) {
						if(result.startsWith("http")){
							http_url=result;
							
							console.log(http_url + '---------1')
						}
					},
					error: function (e, status) {
					  console.log(e.responseText);
					}
				  });
				} 
				//因为不知道二维码啥时候出现,所以做了定时装置。iframe里有个onload事件,自己试了没有成功。
				var myVar = setInterval(function(){
					var frame = document.getElementById("myFrame")
					if(frame){
						document.getElementById("myFrame").src = http_url
						clearInterval(myVar)
					}
				}, 500)
				num++;
				window.localStorage.setItem('first', num);
			}
			</script>
        </#if>
      </#list>
    </#if>
    <#if section = "title">
        ${realm.displayName}
    <#elseif section = "header">
        ${msg("loginTitleHtml",realm.name)}
    <#elseif section = "form">
    </#if>
</@layout.registrationLayout>

还有一个要注意的点,我们的网址环境都是https,当跳转或者取到得是http,则会有跨域报错,因此在template_login.ftl加入了这么一行代码,但是关键点来了,开发的时候把代码注释掉,不然会报错。

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

看一下就好了
在这里插入图片描述

手机验证码登陆,这个就不详细说了,都是很简单的东西。[有需要的可以私聊我]

在这里插入图片描述

还有一个骚操作就是切换的时候二维码必须更新,因为扫码和手机号都是用的同一个code和state所以,切换到二维码时直接
window.location.reload()就可以了

Vue项目里也很简单

import Vue from 'vue'
import VueKeyCloak from '@dsb-norge/vue-keycloak-js'
export function basicsAuth () {
  return new Promise((resolve, reject) => {
    let userInfo = {}
    let vm = new Vue()
    Vue.use(VueKeyCloak , {
      init: {
        onLoad: 'login-required'
      },
      config: {
        url: window.OIDCPATH,
        realm: window.REALM,
        clientId: window.CLIENTID,
        logoutRedirectUri: window.location.href.split('#')[0]
      },
      onReady: keycloak => {
        // alert(JSON.stringify(keycloak))
        keycloak.updateToken()
        window.localStorage.setItem('tk', keycloak.token)
        vm.$http.defaults.headers['Authorization'] = `Bearer ` + keycloak.token
        keycloak.loadUserProfile().success(data => {
          
          userInfo = Object.assign(userInfo, data)
          let unionObj = data.attributes.authInfo[0]
          let unionId = JSON.parse(unionObj).unionid || JSON.parse(unionObj).accountId
          let type = data.attributes.authType[0]
          store.commit('SET_USER_DATA', data)
          setLocalStorage('sd', data)
          store.commit('SET_UNION_ID', unionId)
          getUserInfo(unionId, type)
        })
      },
      onInitError: err => {
        vm.$message({
          type:'error',
          message:'账号异常,请联系管理员,即将返回登录页面!',
          offset:'80'
        })
        setTimeout(function()  {
          window.location.reload();
        }, 3000);
      }
    })
    // 根据unionId获取用户信息
    function getUserInfo (unionId, type) {
      let data = {
        thirdUserId: unionId,
        thirdUserType: type
      }
      vm.$get('', data).then(res => {
        // vm.$http.defaults.headers['userId'] = res.data.userId
        vm.$destroy()
        if (res.code === 200) {
          userInfo = Object.assign(userInfo, res.data)
          resolve(userInfo)
        }
      }).catch(err => {
        console.log(err)
        vm.$destroy()
        reject(err)
      })
    }
  })
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要使用Keycloak单点登录,需要完成以下步骤: 1. 安装Keycloak 2. 创建一个Keycloak Realm 3. 添加一个Client 4. 在Vue应用中安装Keycloak插件 5. 配置Vue应用以使用Keycloak插件 6. 在Vue应用中实现认证和授权 具体的操作步骤如下: 1. 安装Keycloak 可以参考Keycloak官方文档来安装Keycloak,官方文档地址为:https://www.keycloak.org/documentation.html 2. 创建一个Keycloak Realm 可以创建一个Realm,用于存储应用程序的用户,角色和客户端信息。可以参考Keycloak官方文档来创建Realm,官方文档地址为:https://www.keycloak.org/documentation.html 3. 添加一个Client 在Keycloak中添加一个Client,该Client将用于Vue应用的单点登录。可以参考Keycloak官方文档来添加Client,官方文档地址为:https://www.keycloak.org/documentation.html 4. 在Vue应用中安装Keycloak插件 运行以下命令来安装Vue Keycloak插件: ``` npm install vue-keycloak-js --save ``` 5. 配置Vue应用以使用Keycloak插件 在Vue应用中配置Keycloak插件,包括realm,client ID和Keycloak URL等信息。可以参考Vue Keycloak插件的官方文档来配置,官方文档地址为:https://www.npmjs.com/package/vue-keycloak-js 6. 在Vue应用中实现认证和授权 在Vue应用中使用Keycloak插件来实现认证和授权。可以使用Keycloak提供的API来调用认证和授权相关的功能。可以参考Vue Keycloak插件的官方文档来实现认证和授权,官方文档地址为:https://www.npmjs.com/package/vue-keycloak-js 以上就是使用Keycloak单点登录的基本步骤,如果需要更详细的操作步骤,可以参考Keycloak和Vue Keycloak插件的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值