V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dufu1991
V2EX  ›  Apple

Mac 自动填充验证码的探索

  •  1
     
  •   dufu1991 · 2022-05-07 15:05:25 +08:00 · 4962 次点击
    这是一个创建于 712 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    智能手机发展到 2022 年了,不管使用的是 Android 还是 iOS ,当我们收到短信验证码之后,手机会自动提取出其中的验证码并复制出来,如果给的权限够多,它甚至可以帮你自动填充到你正要输入的地方,只是不同系统之间会有些许差别。

    这是我们都已知且习惯的操作。

    当然,验证码作为当前越来越重要的一种安全验证工具,允许软件如此自由获取到验证码是一件非常危险的事情,所以最好不要允许系统外的第三方后台联网输入法来读取它。

    但是,如果你使用的是桌面设备,那如何将手机收到的验证码自动在桌面设备上填充呢?

    探索

    众所周知,如果恰好同时使用了 Mac 与 iPhone ,这个操作 Apple 也已经为你做好了(部分)。

    参考将 iPhone 中的短信 /彩信转发到 iPad 、iPod touch 或 Mac 。

    当手机收到短信时将会自动同步到同一个 Apple ID 登录的 Mac 上面。

    如果你使用的正好是 Mac 自带的 Safari 浏览器来填充验证码,恭喜你,你不用做任何操作,你将可以在 Safari 上面点一下直接填充手机收到的验证码。

    延伸

    由于 Apple 的隐私限制,在 Safari 之外比如 Chrome 等 Apple 生态外的软件内我们是无法如此方便地填充验证码的。

    咋办,有人和我一样懒吗?

    有人用 ohtipi 方案,但是好像收费而且仅仅限制在浏览器内。

    也有其他脚本方案的。

    Bokun 的方案 是做定时器每分钟跑一次,这种不高频的操作做定时器后台一直跑,感觉有点过了,我参考做了个适合我的手动方案。

    大致原理

    Mac 收到的信息内容会存储在 /Users/${Your Name}/Library/Messages/chat.db 这个文件内,通过脚本读取最近 60 秒的一条信息内容,如果有验证码信息,通过正则筛选出其中的验证码,并复制到剪贴板,成功与否都给出一条系统通知。

    步骤

    1. 在你喜欢的地方新建一个 shell 脚本文件(比如 /Users/${Your Name}/Shells/AutoCheckCode.sh,文件内容在文末),给此文件授予当前用户读与写的权限(选中文件 ⌘+I )。

    2. 测试一下此脚本是否正确,使用系统自带终端或者 iTerm ,cd 到存放上一步文件的目录内,执行 ./AutoCheckCode.sh,成功与否都将收到一条提示。到这一步,后面只需要考虑如何以最快速的方式执行这个脚本。

      需要注意无论使用自带终端、快捷指令、自动操作、或者 iTerm 等执行此脚本,都需要到系统偏好设置-安全与隐私-隐私-完全磁盘访问权限,打开对应软件的权限。

    3. Mac 上快速执行脚本有很多方式,我也都进行了尝试。

      • 考虑使用 Mac 新版本的快捷指令,运行 Shell 脚本,报错放弃。👎🏻
      • 使用 Mac 的自动操作编写一个快速操作,然后到系统偏好设置-键盘-快捷键-服务-通用,将刚刚写的操作配置一个快捷键,看起来完美。可是运行发现必须要自动操作这个 APP 在前台才能成功,放弃。👎🏻
      • 使用自动操作创建一个应用程序,程序内选择运行 shell 脚本,脚本内容为 sh /Users/${Your Name}/Shells/AutoCheckCode.sh,保存此应用至 Mac 的应用程序目录之内,名称看个人喜欢,比如「复制验证码.app 」。同时记得给这个应用完全磁盘访问权限。👍🏻
    4. 此时相当于你已经开发打包并安装了一个 Mac 的应用程序,虽然它很简单。

    5. 触发这个程序的方式那就更多了,Alfred 、HapiGo 、Raycast ,甚至手动点击一下也是可以的,当 Mac 收到短信的时候,执行一下应用即可。

    脚本内容

    #!/bin/bash
    
    echo "starting to check code";
      # 路径中的 dufu 记得改成自己电脑的名字
      # 通过 Sqlite3 查 1 条 iMessage 最近 60 秒收到消息( iMessage 收到消息的时间可能有延迟,这里实际冗余多了 2 秒)
      #! /Users/dufu/Library/Messages/chat.db
      #!这个 DB 文件和目录记得给开权限,默认是不给读的。
      result=$(sqlite3 /Users/dufu/Library/Messages/chat.db 'SELECT text FROM message WHERE datetime(date/1000000000 + 978307200,"unixepoch","localtime") > datetime("now","localtime","-60 second") ORDER BY date DESC LIMIT 1;')
    
      name="验证码";
    
      # 看下最近有没有收到消息
      if [ ! $result ]; then
          echo "latest not receive code messsages";
          osascript -e "display notification \"最近 60 秒未收到验证码!\" with title \"提示\"   ";
          return
      fi
    
    #   如果短信中包含验证码则取前 4-6 个数字
      if [[ "$result" =~ "$name" ]]; then
          code=`echo $result | grep -o "[0-9]\{4,6\}"`;
          echo "code is $code";
          # 将获取到的数字输出到剪贴板
          echo "$code" | pbcopy;
    
          # 发个系统通知,展示内容,同时提醒你可以 Command + v 粘贴了。
          osascript -e "display notification \"$code\" with title \"验证码已复制\"";
      fi
    
    

    题外

    另外也可以使用 Mac 的脚本编辑器,输入以下 AppleScript (我使用了 iTerm ),保存时文件格式选择应用程序

    tell application "iTerm"
    	activate
    	create window with default profile command "sh /Users/dufu/Shells/AutoCheckCode.sh"
    end tell
    
    

    如果觉得创建的这个 APP 图标不好看,可以复制一张图片,在访达里选中这个应用,按 ⌘+I ,选中应用图标 ⌘+V ,将你的应用图标替换。

    第 1 条附言  ·  2022-05-11 08:35:28 +08:00
    除了我这种将脚本打包成 APP 手动执行方案,Bokun 的每分钟执行一次方案,有其他平台的用户提供了另外一条思路,通过 launchctl 服务( WatchPaths )监看 chat.db 文件是否发生变化,如果发生变化,则执行指定的脚本。
    他没有写具体的实现方法,感兴趣的可以自己研究一下。
    41 条回复    2022-12-20 08:29:50 +08:00
    CenN
        1
    CenN  
       2022-05-07 15:49:50 +08:00
    有用👍🏻!能否在读取验证码之后将短信设置为已读呢?
    zhaidoudou123
        2
    zhaidoudou123  
       2022-05-07 16:12:10 +08:00
    很实用,但是 ohtipi 似乎能实现和 Safari 一样的效果,不过要$5 ,有些贵了
    仔细一想,我还是 Safari 用的多,真正需要在别的地方填写验证码的机会屈指可数🤣 另外,macOS 上运行的 iOS 应用似乎可以直接调用验证码
    hn16838220
        3
    hn16838220  
       2022-05-07 16:19:28 +08:00
    赞,前两天看到有人分享这个思路,没想到已经有人做出来了
    dufu1991
        4
    dufu1991  
    OP
       2022-05-07 16:24:52 +08:00
    @zhaidoudou123 苦逼前端开发,Safari 完全无法用。😭
    dufu1991
        5
    dufu1991  
    OP
       2022-05-07 16:25:36 +08:00
    @CenN 你研究一下,我不是刚需。
    Thinkerous
        6
    Thinkerous  
       2022-05-07 16:26:53 +08:00
    @zhaidoudou123 刚看了下 setapp 订阅里面包含了
    JimmyLX
        7
    JimmyLX  
       2022-05-07 17:18:57 +08:00
    @Thinkerous #6 对,本来还想买的,结果 setapp 有,下来用了挺好用的

    既然短信端搞定了,蹲一个邮件端的验证码收集器
    ritsurin
        8
    ritsurin  
       2022-05-07 19:00:31 +08:00
    fluffyfoxxo
        9
    fluffyfoxxo  
       2022-05-07 19:07:13 +08:00
    赞楼主,我一直嫌 ohtipi 太大,而且最近出了用不了的 Bug ,抛弃之。
    同时补充一下,经过测试,12.3 在快捷指令中运行成功。
    不要给 Shortcuts.app 完全磁盘访问权限,给 siriactionsd 就可以正常使用了
    fluffyfoxxo
        10
    fluffyfoxxo  
       2022-05-07 19:07:40 +08:00
    @fluffyfoxxo 系统版本 12.3.1 ,不是 12.3
    dufu1991
        11
    dufu1991  
    OP
       2022-05-07 19:20:14 +08:00
    @fluffyfoxxo 试了一下“siriactionsd 就可以正常使用了”确实可以了,还是你细。不过打包成一个 app ,好像更方便。
    fluffyfoxxo
        12
    fluffyfoxxo  
       2022-05-07 19:53:49 +08:00
    用了一下发现要加一个 | head -1 参数
    ```code=`echo $result | grep -m1 -o "[0-9]\{4,6\}" | head -1`;```
    因为会有这种短信:

    > 验证码 012345 ( 1 分钟有效),请勿告知他人。您尾号 67890 的账户正在开通京东支付公司的协议支付功能 [华夏银行]

    > [TWLNET]012345 is your Playasia Verification Code. Tap <https://playasia.com/??rv=012345-6789012-3456789012>
    dufu1991
        13
    dufu1991  
    OP
       2022-05-07 20:41:13 +08:00
    @fluffyfoxxo 确实是这样,不过我发现如果是和样,『您尾号 67890 的账户正在开通京东支付公司的协议支付功能,验证码 012345 ( 1 分钟有效),请勿告知他人。您尾号 的账户正在开通京东支付公司的协议支付功能 [华夏银行]"』的话,好像也有问题,取前面的话会取到 67890 。这个正则不熟,大佬帮忙想想如何匹配万无一失?
    fluffyfoxxo
        14
    fluffyfoxxo  
       2022-05-07 21:05:28 +08:00
    @dufu1991 哈哈翻遍了所有的短信,觉得大部分应该都是验证码在最前面,结果居然还真碰到例外了。
    > [12366] 尊敬的平台用户您好,您正在注册平台用户,您的验证码为[964356],请在 10 分钟内验证。
    我也没辙,蹲一个大佬
    alanhe421
        15
    alanhe421  
       2022-05-07 21:13:08 +08:00
    嗯,都是读了短信 DB 文件,然后查出来短信信息,正则匹配。
    logyxiao
        16
    logyxiao  
       2022-05-07 22:22:55 +08:00
    脚本可以用$HOME 代表根目录 就不用改了

    result=$(sqlite3 $HOME/Library/Messages/chat.db ...')

    另外刚刚试了一下用 raycast 添加了这个脚本,可以直接执行
    IslandOwnerHuang
        17
    IslandOwnerHuang  
       2022-05-08 09:26:21 +08:00
    感谢,已购买 ohtipi ,总算解决了 Chrome 自动填充验证码的问题了👍
    Leung818
        18
    Leung818  
       2022-05-08 14:22:03 +08:00
    @fluffyfoxxo 我也是 12.3.1 系统,但是在 cmd + i 给 Message 和 chat.db 读与写的权限后,再执行还是会报「 authorization denied 」的错误
    Silently
        19
    Silently  
       2022-05-09 07:58:25 +08:00 via iPhone
    非常好、下班后装一下
    azel
        20
    azel  
       2022-05-09 13:10:38 +08:00   ❤️ 1
    @Leung818 还有一个是给执行这个脚本对应程序的权限;比如我是用 Raycast 执行的,需要给 Raycast 完全磁盘访问权限才行。
    Leung818
        21
    Leung818  
       2022-05-09 13:50:04 +08:00
    @azel soga~这么一说我就明白了
    dufu1991
        22
    dufu1991  
    OP
       2022-05-09 14:32:25 +08:00
    @Leung818 考虑到这个情况,文章中已经说了哦。😸
    gqbre
        23
    gqbre  
       2022-05-09 19:26:15 +08:00
    看了一圈,发现又出了个 2fhey ,使用 swift 重写,谁试试。。
    gqbre
        24
    gqbre  
       2022-05-09 19:33:58 +08:00
    ohtipi 改名为 2FHey ,限免下载,冲~~ https://www.v2ex.com/t/851824
    structuralcbh
        25
    structuralcbh  
       2022-05-10 11:57:55 +08:00
    所有权限都给了,还是提示
    zsh: permission denied: ./AutoCheckCode.sh
    dufu1991
        26
    dufu1991  
    OP
       2022-05-10 12:29:14 +08:00
    @structuralcbh 应该是你没有读取这个文件的权限。参考: https://www.jianshu.com/p/bdc59fb50743
    MrCharlesWu
        27
    MrCharlesWu  
       2022-05-10 12:45:01 +08:00 via Android
    有没有安卓和 MAC 搭配在 MAC 上自动填写验证码的方案?
    dufu1991
        28
    dufu1991  
    OP
       2022-05-10 13:13:50 +08:00
    dufu1991
        29
    dufu1991  
    OP
       2022-05-10 13:27:16 +08:00
    @dufu1991 首先从 Android 到 Mac 这一步就比较麻烦,得有个服务器帮你转发,手机和 Mac 两端都需要客户端发与收,手机上还随时后台得有个程序监控短信(高风险),耗电也是个问题。
    感觉得不偿失。
    dufu1991
        30
    dufu1991  
    OP
       2022-05-10 13:27:55 +08:00
    @MrCharlesWu 首先从 Android 到 Mac 这一步就比较麻烦,得有个服务器帮你转发,手机和 Mac 两端都需要客户端发与收,手机上还随时后台得有个程序监控短信(高风险),耗电也是个问题。
    感觉得不偿失。
    MrCharlesWu
        31
    MrCharlesWu  
       2022-05-10 14:01:12 +08:00 via Android
    @dufu1991 好的,谢谢,现在就在用这一套方案了,只是他不能实现自动填写。不过已经算安卓跟 MAC 搭配的最好方案了。
    jmitch
        32
    jmitch  
       2022-05-11 00:24:19 +08:00   ❤️ 3
    Hey everyone! I just released 2FHey (remake of Ohtipi) if you're interested in getting an app that does this.
    Achieve7
        33
    Achieve7  
       2022-05-11 14:32:44 +08:00
    数据库路径可以改成 ~/Library/Messages/chat.db 就不用在意路径的问题了
    dufu1991
        34
    dufu1991  
    OP
       2022-07-05 11:52:36 +08:00
    你们都是从哪里看到跳转过来的吗?过了这么久,怎么今早突然这个帖子收藏感谢增加了很多。
    SimonOne
        35
    SimonOne  
       2022-07-05 12:34:48 +08:00
    SimonOne
        36
    SimonOne  
       2022-07-05 12:40:07 +08:00
    @dufu1991 #34 op 你好,有个问题想咨询下,我的 mac 信息,同步之后消息是不全的,最近的信息里有的有有的没有,再次点击同步也是。有什么好的解决办法吗 😂
    SimonOne
        37
    SimonOne  
       2022-07-05 13:07:23 +08:00
    @dufu1991 #34 我找到了,在 iphone 设置-信息-短信转发那里,我还以为在 icloud 那里呢,苹果的配置真的是东一块西一块的
    jiobanma
        38
    jiobanma  
       2022-07-06 11:10:08 +08:00
    试了一下,可以成功的,但是要手动点击才可以获取到验证码是吗?有没有自动的方案
    ricky077
        39
    ricky077  
       2022-12-19 18:45:34 +08:00 via iPhone
    OP 请教一下,单独 bash 执行能获取到验证码,通过 launchctl 监听执行一模一样的 shell ,获取不到验证码,但是通知弹了框的,感觉是 db 权限的问题,自动执行不是用户组?
    ricky077
        40
    ricky077  
       2022-12-19 22:50:21 +08:00
    @azel 感谢,研究了 4 个小时终于解决这个问题了。终端执行能获取验证码,就是 launchctl 执行就报错,看到你这个才恍然大悟,没给 bash 权限~
    dufu1991
        41
    dufu1991  
    OP
       2022-12-20 08:29:50 +08:00
    @ricky077 如果是想折腾一下可以玩玩,如果只是为了实现这个功能,可以关注一下这里,https://github.com/LeeeSe/MessAuto ,有点小问题作者正在处理。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5715 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 02:16 · PVG 10:16 · LAX 19:16 · JFK 22:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.