前言

其实所说的被挤下线功能,就是一个账号在A客户端保持登陆状态,然后又在B客户端进行了登陆操作,那么A客户端就会被顶下线

很多伙伴在开发自己公司产品的时候,一般都会考虑用户账号安全,或者用户账号功能限制等问题,这时候就要考虑到单点登陆的功能


使用

App如何知道该账户已经在其他设备上登陆了呢?有三种实现方式

  1. api请求中后台返回特定的code。缺点是需要下次请求才知道被踢下线
  2. 使用推送。后台可以推送给APP,从而使APP得知已在其他地方登陆,可以及时响应
  3. 我们的项目中集成了环信的即时聊天,所以就使用了环信的监听器监听用户状态,用来判断是否已在其他地方登陆,实现挤下线功能

服务端需要返回 Token,每次在app登录时为 app 分配一个新的 token,如果在某次请求中 app 传递 token不是最新的,则视为需要重新登录,在token失效的情况下,返回约定好的code

环信

使用第三方的监听器。比如集成了环信,环信自身有提供连接状态的接听,通过监听环信的用户状态,从而达到监听app自身用户系统的效果

我们的项目中集成了环信的即时聊天,所以就使用了环信的监听器监听用户状态,用来判断是否已在其他地方登陆,实现挤下线功能。

具体实现: 
1.首先在初始化环信的时候设置一个全局的监听器里面注册一个连接监听

// 注册连接监听
EMChatManager.getInstance()
.addConnectionListener(connectionListener);
  • 1
  • 2
  • 3

2.实现这个连接监听的那个检测到连接断开的时候是用户被移除还是连接冲突即账号在其他地方登陆,做出相应的操作

// create the global connection listener
connectionListener = new EMConnectionListener() {@Overridepublic void onDisconnected(int error) {if (error == EMError.USER_REMOVED) {onCurrentAccountRemoved();} else if (error == EMError.CONNECTION_CONFLICT) {onConnectionConflict();}}@Overridepublic void onConnected() {// in case group and contact were already synced, we supposed to// notify sdk we are ready to receive the events}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3.我们关心账号在别处登陆,这个时候,我们一般要条红钻到MainActivity,然后强制弹出对话框提示用户重新登陆

/**
* 账号在别的设备登录
*/
protected void onConnectionConflict() {Intent intent = new Intent(appContext, MainActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.putExtra(Constant.ACCOUNT_CONFLICT, true);appContext.startActivity(intent);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这个地方检测到登陆冲突之后需要回到MainActivity,并为MainActivity携带了一个标识和一个标记位Intent.FLAG_ACTIVITY_TASK,表示在一个新的task中开启一个Activity,如果包含这个Activity的task已经在运行,那么这个Activity就回到前台显示,然后回调onNewIntent()方法处理这个Intent 
4.回到MainActivity中的onNewIntent()方法

@Override
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);if (intent.getBooleanExtra(Constant.ACCOUNT_CONFLICT, false) && !isConflictDialogShow) {showConflictDialog();} else if (intent.getBooleanExtra(Constant.ACCOUNT_REMOVED, false)&& !isAccountRemovedDialogShow) {showAccountRemovedDialog();}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

首先会判断表示,如果时账户冲突就会提出对话框提示用户跳转登陆页面重新登陆,另外这个对话框是不能取消也不可关闭的

这样被顶下线功能就基本实现了

Token

1.创建一个token 
首先我们要在服务端创建一个token的值,这个值是和userid以及手机号码绑定到一起的,也就是请求token的时候我们要给服务端传递当前设备以及用户id。token这个值就是客户端调用服务端的凭证 
android中获取唯一标识 deviceid

//deviceId  public static String getDeviceId(Context context) {  TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);  if (tm == null) {  return "";  }  return "" + tm.getDeviceId();  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

但是这个很多机器是无法获取到的这个值,所以后来改为mac地址,mac地址很好理解,就是用户上网的上网许可证,这个买手机的时候,你翻开电池就知道里面有一个标签!!

/** * 获取MAC地址,注意:手机重启,mac地址为null; *  * @param context * @return mac地址; */
public static String getMac(Context context) {  if (context != null) {  WifiManager wifi = (WifiManager) context  .getSystemService(Context.WIFI_SERVICE);  WifiInfo info = wifi.getConnectionInfo();  return info.getMacAddress();  } else {  return "";  }
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.获取token 
app进入时要先获取token,获取token的时候我们要给服务端传递当前设备的设备号,当我们换了设备后设备号变了,返回的token值也就变了,那么原设备的token相对来说就失效了,当在原设备和服务端有交互的时候会返回token失效,用户登陆注销要及时更新token值 
3.请求交互携带token 
每次客户端和服务端有任何交互的时候都要传递这个token参数,当我们在另一台设备登陆的时候原设备上存的token就失效了,因为数据库里当前用户的token已经在新设备获取token值的覆盖了,这样原设备请求时就回提示token值失效了 
4.根据服务端返回码处理逻辑 
事先客户端和服务端要约定好一个code码,咧如:我们约定返回码为99的时候代表token失效,那么当我们请求服务端返回值为99的时候就要提示您的登陆转台失效,请您重新登陆

switch (code) {  case 1:  break;  case 99://被踢下线  //Do Something  break;  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

上面说了自己用自己的业务系统实现app单点的基本流程

Android 集成环信实现单点登录校验,账号异地被挤下线功能。相关推荐

  1. 最新Android集成环信步骤详解

    前一阵时间一直以为环信不能被个人用户注册,结果现在想试试结果真的注册进来了,各种打脸.今天趁着晚上有时间把环信继承的步骤做一个记录,方便以后的童鞋们能够快速的集成. 1.第一步:肯定是创建应用喽 那么 ...

  2. Android集成环信easeui,设置圆形头像,修改气泡和扩展栏,跳过打包冲突

    初次集成环信的话还是有很多坑的, 我也是个新手,技术客服各种问,各种找人,才堪堪摸到门槛,记录下一点东西,希望给那些初次集成的朋友一点tips. 1,集成环信的时候,如果你不需要很多如视频聊天,等的功 ...

  3. Android集成环信IM,实现聊天置顶功能

    首先是,要实现置顶聊天,那么我们就要有两个List集合,一个是置顶的,一个是不是置顶的.这里,环信给出了EMConversation的一个方法,带大家看看技术文档. 看下这个文档里面说的非常清楚,也就 ...

  4. Android 集成环信IM,实现头像和昵称的显示

    环信中要设置昵称和头像有两种方法,一种是通过请求服务器获得,一种是通过发送扩展消息获得.本人推荐通过发送扩展消息获得,简单又方便.所以下面我就只讲通过发送扩展消息获取的方法. 具体的实现步骤如下: 1 ...

  5. android 集成环信SDK

    集成步骤: 1. 首先在你的项目根目录build.gradle文件的allprojects→repositories属性下加入远程库地址 allprojects {repositories {goog ...

  6. Android集成环信IM,实现为某一个好友设置消息免打扰

    环信SDK中是没有提供直接为某一个好友设置消息免打扰的api,其实,所谓的消息免打扰,无非就是在收到好友的消息时,不进行通知,在会话列表中,不显示未读消息数量,因此,我们可以将是否开启免打扰的的状态保 ...

  7. android 集成环信 即时通讯

    工作这么长时间了,我是一个很懒的人 ,今天正好看见前同事在CSDN上发的博客,记录了那时我们一起工作碰到的问题,勾起了美好的回忆,索性我在记录一下刚刚做完的一些功能,花了将近多半个月做了环信的即时通讯 ...

  8. Android 集成环信后 无法启动,关于androidx升级后环信sdk集成遇到的问题

    18年谷歌对support包等依赖混乱的问题进行了决策并推出androidx,可以有效的解决support包的问题,但版本迁移带给我们程序员很多麻烦的问题,就是之前的sdk很多都会报错,这里用环信的s ...

  9. Android 使用easeui 3.0 集成环信即时通讯 我踩过的坑

    0.关于注冊账号就不用说了. 1.创建应用.获取appkey 0.创建应用 1.填写信息 2.获取appkey 2.集成 0.首先新建一个project 1.这里主要介绍使用easeui来集成环信的即 ...

最新文章

  1. 兼容及DOM解释差异笔记——待续
  2. python练习9-7
  3. XCTF_Web_新手练习区:cookie
  4. 数据库服务器的文件结构6,以下数据库服务器的文件结构
  5. 初学者:如何使用虚拟PC将Windows 7安装到虚拟机
  6. 【ArcGIS Pro微课1000例】0006:ArcGIS Pro 2.5三维显示DEM数字高程模型
  7. 2018 蓝桥杯省赛 B 组模拟赛(一) 封印之门+最短路径之Floyd
  8. java中数据成员的初始化问题
  9. 《小强与小明》——正在疯传的伟大的故事
  10. oracle设置控制文件多路径,【备份恢复】 控制文件多路径
  11. 利用Kafka发送/消费消息-Java示例
  12. 模拟存储器管理C语言,操作系统-存储器管理实验C语言.doc
  13. U-boot下Nand Flash的相关命令
  14. 了解typename的双重意义
  15. 基于 Python 与 mxget 的音乐下载器
  16. Spider爬虫框架之Spiders模块
  17. 树状数组————(神奇的区间操作)蒟蒻都可以看懂,因为博主就是个蒟蒻...
  18. C++:实现量化daycounters 日计数器测试实例
  19. 期待台湾出现 OpenNMS Certified Partner
  20. (四十五:2021.08.05)《利用深度学习对ecg信号进行分割》

热门文章

  1. SpringBoot Security的自定义异常
  2. 运维必备——ELK日志分析系统
  3. 利用Echarts+Springboot实现数据可视化 数据可视化 Spring实现简单的数据可视化 自定义可视化图表
  4. Pandas中的Series对象详解(含Python代码)
  5. 使用python判断同名文件
  6. 如何打开导出的EML邮件文件并且合并到EXCEL表
  7. 如何在树莓派上安装 Fedora 25
  8. C++ ifstream open 读取txt/json文件出现中文乱码的解决问题
  9. 基于飞桨paddlepaddle复现StarGAN v2
  10. jmeter接口测试传参问题汇总