首先不妨先看下Android:扫描二维码登陆原理:

大概总结下这个过程就是:

  1. 服务器生成全局唯一会话ID,并返回二维码、过期时间;
  2. 用户扫描二维码,提交改会话ID,用户基本信息到服务器;
  3. PC端在过期时间内一直轮询,如果用户扫码,服务器记录状态,PC端跳转到已登录页面;

那不妨按照这个思路来写一个简单的Demo

1. 后台

首先,我们需要搭建一个简易版的后台。在IDEA中创建SpringBoot项目,然后添加thymeleaf和session的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-core</artifactId>
</dependency>

然后,我们这里模拟Demo,不需要数据库,故而模拟系统中已注册用户,可以使用Set集合来存储。模拟记录系统登录用户来使用Map存储。然后将之封装到一个Bean对象中。同样二维码这里也直接使用一张静态二维码,内容为:

http://192.168.1.102:8080/scanlogin?uuid=Wxfsfdfskfj==
@Component
public class UserMap {private static Map<String, User> loginmap = new HashMap<String, User>();private static Set<User> users = new HashSet<>();

项目结构如下:

添加对应的html页面,在loginpage.html中显示二维码,并进行轮询:

<body><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><center><div>login page!</div><img src="code.png" style="width=300px; height=300px;"><div style="color:red;" id="info"></div></center><script>var getting = {url:'http://192.168.1.102:8080/checkscan',data:{"uuid": "Wxfsfdfskfj=="},dataType:'text',success:function(res) {if(JSON.parse(res)){$('#info').html("已授权");setTimeout(function(){window.location.href = 'http://192.168.1.102:8080/home';},1000);}else{$('#info').html("未授权");}setTimeout(function(){$.ajax(getting);},1000);},error:function(res){$('#info').html("请求发生了未知错误!");}};$.ajax(getting)</script>
</body>
</html>

然后就是Controller的Android端扫码后确认授权接口:

@GetMapping(value="/scanlogin")
@ResponseBody
// 手机端确定登录后调用该接口,将用户加入到登录Map
// http://localhost:8080/login?uuid=Wxfsfdfskfj==&userid=qwe&username=123
public String scanLogin(HttpSession session,@RequestParam("uuid") String uuid,@RequestParam("userid") String userid,@RequestParam("username") String name){String UUID = "Wxfsfdfskfj==";User user = new User(name, userid);if(uuid.equals(UUID) && userService.checkUserInfo(user)){UserMap.loginUser(UUID, new User(name, userid));return "SUCCESS LOGIN!";}else {return "ERROR UserInfo!";}
}

在请求主页home的时候,需要判断用户是否登录,即校验Session

@GetMapping(value="/home")
// 校验Session的主页
public String getHomePage(HttpSession session){String username = (String) session.getAttribute("name");if(username == null){return "redirect:/notlogin";}return "homepage";
}

前端ajax轮询接口:

@GetMapping(value="/checkscan")
@ResponseBody
// 需要前端轮询这个接口,判断是否确认登录
public boolean hasScan(HttpSession session,@RequestParam("uuid") String uuid){User scanedUser = UserMap.getScanUserByUUID(uuid);if(scanedUser == null)return false;if(userService.hasUser(scanedUser.getUserID())){String username = (String) session.getAttribute("name");if(username == null){session.setAttribute("name", uuid);}return true;}return false;
}

2. Android端

首先添加两个依赖:

implementation 'cn.yipianfengye.android:zxing-library:2.2'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'

zxing是一个使用非常简单的扫码封装。项目地址:here

按照文档说明进行集成即可。页面非常简单,两个页面:
MainActivity中显示一个按钮,模拟扫码入口,调用后扫码后返回结果;

LoginActivity中进行提示用户确认授权,进行确认接口请求;

MainActivity中添加权限申请:

<uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
// 请求读写权限
if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//申请权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA}, 1);
}
if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {//申请权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.INTERNET}, 1);
}

进行点击按钮的跳转

Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, 1);

复写onActivityResult方法(CaptureActivity中调用setResult,然后finish()):

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {//处理扫描结果(在界面上显示)super.onActivityResult(requestCode, resultCode, data);if(requestCode == 1){Toast.makeText(this, String.valueOf(null != data), Toast.LENGTH_LONG).show();if (null != data) {Bundle bundle = data.getExtras();if (bundle == null) {return;}if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {String result = bundle.getString(CodeUtils.RESULT_STRING);Intent intent = new Intent(MainActivity.this, LoginActivity.class);intent.putExtra("url", result);startActivity(intent);} else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();}}}
}

在启动的LoginActivity中进行确认授权接口进行GET请求:

public void requestLogin() {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(url).build();client.newCall(request).enqueue(new Callback() {Message msg = new Message();@Overridepublic void onFailure(Call call, IOException e) {msg.obj="请求失败";handler.sendMessage(msg);}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {if (response.code() == 200) {String result = response.body().string();if(result.equals("SUCCESS LOGIN!")){msg.obj = "授权成功!";}}}else{msg.obj = "出现了未知错误: " + response.code();}handler.sendMessage(msg);}});
}

3. 效果:

扫码前,我们直接home;扫码后Ajax处理直接跳转到主页home。

Demo地址

https://github.com/baiyazi/ScanQrCodeAndAutoLoginDemo

Android 扫码登录案例相关推荐

  1. Android 扫码登录

    国际惯例:先上图: tip,用ssm做的后台. 具体思路: 1.准备一个bean(存放用户信息的类和记录是否同意登录的Boolean属性) 和 一个map,存放类型为bean(存放用户信息的类) 2. ...

  2. 用Android和node.js实现扫码登录

    实现思路 step 1: 网页端提供二维码 step 2: 手机端登录,并保存token,手机扫码后向网页端发送token step 3: 网页端通过jstoken解析token,向后端服务器获取用户 ...

  3. 微信扫码登录网站实现案例(无需授权)

    前言 最近因业务需要,需要给网站增加一个扫描公众号二维码登录网站的功能,通过扫码登录,一来用户登录网站不需再输入账号密码,提升了用户体验,二来也可以作为公众号吸粉的一个渠道. 开发准备 实现微信扫码登 ...

  4. Android集成微信SDK扫码登录功能

    最近做一个android项目,需求是登录页面加入微信二维码扫码登录入口(类似于PC端扫一扫登录),用户打开微信APP,扫描二维码,点击登录即可.当时也看了官网的相关介绍,确实踩了不少坑,写这个博客记录 ...

  5. IM要做手机扫码登录?先看看微信的扫码登录功能技术原理

    本文原文由作者Amazing10原创发布于公众号业余码农,收录时有改动,感谢原作者的技术分享. 1.引言 某天中午,吃完午饭,摊在自己的躺椅上,想趁吃饱喝足的午后时间静静享受独自的静谧. 干点什么好呢 ...

  6. 一文详析微信和淘宝扫码登录背后的实现原理!

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 作者:imtech my.oschina.net/u/4231722/blog/3 ...

  7. Spring Boot 实现扫码登录,这种方式太香了!!

    作者 | 93年颈椎病人 来源 | https://blog.csdn.net/q826qq1878/article/details/91041679 最近有个项目涉及到websocket实现扫码登录 ...

  8. 面试官:说说微信和淘宝扫码登录背后的实现原理?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | my.oschina.net/u/423172 ...

  9. 钉钉扫码登录第三方_在钉钉发布公司重要文件,真的安全吗?

    钉钉以疫情在家办公为契机,加上"幸运地"被教育部"选中",在2月5日,钉钉下载量首次超过微信,跃居苹果App Store排行榜第一,并打破App Store记录 ...

最新文章

  1. 代码对比工具,我就用这 6 个!
  2. 2020 我的C++的学习之路
  3. 卡尔曼滤波与组合导航原理_卫星知识科普:一种基于卫星共视的卡尔曼滤波算法!...
  4. C#如何用正则表达式截取https和带端口的域名
  5. SpringBoot集成logback彩色日志配置以及banner启动设置(炫酷到爆炸!)
  6. jquery 数组indexof_如何实现一个简化版的 jQuery
  7. 【Vue】路由Router嵌套的实现及经典案例
  8. linux下定时执行任务方法【转】
  9. [ NOI 2005 ] 聪聪与可可
  10. android模拟机型,(安卓)牛X分身 — 支持位置模拟机型修改
  11. cad计算机清空按键,cad delete键不能用怎么办-解决cad按delete键不能删除的方法 - 河东软件园...
  12. 红酒百科知识(二)_manok_新浪博客
  13. 转载一个手机RPG游戏制作工具,仿造RPGXP写的
  14. 一个简单的BitTorrent客户端实现(五):tracker manager和tracker实现
  15. logback高级特性使用(一)
  16. 李狗蛋和二狗子因为HTTP or RPC打起来了No.135
  17. Redis 3.2.3 crashed by signal: 11 服务宕机问题排查
  18. SDCC教程(树莓派 Debian11 bullseye 使用官方下载源)
  19. stable_sort的含义
  20. 月薪2万的Java工程师简历是这样的

热门文章

  1. 第2部分 字符串算法(提高篇)--第2章 KMP算法1469:似乎在梦中见过的样子
  2. abcd\110的字节数、字符长度以及字符
  3. 图像美化和图像处理哪个属于计算机应用,情境体验在计算机图像处理教学中的应用...
  4. uni 页面加载完毕_uni-app图片未加载完处理
  5. 淄博旅游景点与美食汇总
  6. 支付宝/微信手机网站支付总结
  7. 《士兵突击》之伍六一:最钢铁的男儿最柔软的内心
  8. 广东省韶关市谷歌卫星地图下载
  9. Java入门123:一个老鸟的Java学习心得(二维码版)
  10. [CTO札记]武侠人物名称稀缺,上起点找吧