Oauth的学习以及开发自助上课签到脚本
附上源码: https://github.com/taka250/auto_checkin_skl_hdu
首先了解学习oauth的知识点
https://www.cnblogs.com/blowing00/p/4521135.html
http://cncc.bingj.com/cache.aspx?q=oauth2.0&d=4769308101185638&mkt=zh-CN&setlang=zh-CN&w=7GpK0TUY9vh41MBeGv6mo3zlrgdPnO7v 推荐这位老师写的文章
其中的授权码模式
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
A.用bp抓包第一个请求时
将我们导向了客户端指定的uri(保存在get参数中),响应头也将我们302到了实现指定的uri(ticket就是授权码)。前提是用户给予了授权,在此情况下是用rsa对用户名密码进行验证。
我还发现了请求中包含了state参数。研究了一下是防止csrf的
然后就是拿到token了
要注意你电进行了两次拿token两次设置cookie,第一个token无用(。。。)
登录加签到
首先学校的login.js里面
然后我看了下strEnc函数
/**
* DES加密解密
* @Copyright Copyright (c) 2006
* @author Guapo
* @see DESCore
*/
/*
* encrypt the string to string made up of hex
* return the encrypted string
*/
function strEnc(data,firstKey,secondKey,thirdKey){
var leng = data.length;
var encData = "";
四个参数,第一个是用户名加密码加登录浏览器时的第一个页面中的某个元素的value(lt) 所以说还需要爬虫。
明明是des加密说是rsa(-v-。。。。跟rsa半毛钱关系都没有。。。。之前还有人分析说这是rsa和des双重加密。。笑)本来想在python里解析js代码或者将js翻译为python后来发现一个配置很麻烦一个用esecjs库翻译的结果运行效率很慢显然来不及签到。那我就直接去写python的des加密脚本。等我学完des准备写的之后才想起来可以去github上找代码。。。(就当学习一次des)然后strEnc的三个参数等我看完原函数后了解了这个其实就是对结果进行三次加密des而已。附上我在github上找到的python代码https://github.com/twhiteman/pyDes (网上的都是只能对一个64位进行加密需要我改写)巨折磨,这个2006年的js代码将四个字符扩充64位明文,而其他库都是八位进行一次加密,太烦了,我还是在本地启动一个node服务器来跑代码试试。
所以我挂了三个进程 qbot 和node服务器加密和python进行checkin
附上python server的代码
from flask import Flask, request
import Skl
import account
app = Flask(__name__)
@app.route('/', methods=["POST"])
def post_data():
if request.get_json().get('message_type') == 'group' and request.get_json().get('group_id') == int(account.group):
print(account.group)
gid = request.get_json().get('group_id')
uid = request.get_json().get('sender').get('user_id')
message = request.get_json().get('raw_message')
skl = Skl.Skl()
if skl.check_num(message, uid, gid):
skl.autocheck(message, account.user_1,
account.passwd_1, account.group)
skl.autocheck(message, account.user_2,
account.passwd_2, account.group)
return 'ok'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8001)
和封装的Skl类
import requests
import re
import uuid
import time
class Skl(object):
def check_num(self, message, uid, gid):
if re.match(r'^[0-9]{4}$', message):
self.code = message
return 1
return 0
def spider(self):
response = requests.get(
'https://cas.hdu.edu.cn/cas/login?state=IFgP7G0QAG0UFHop0M4&service=https%3A%2F%2Fskl.hdu.edu.cn%2Fapi%2Fcas%2Flogin%3Fstate%3DIFgP7G0QAG0UFHop0M4%26index%3D')
response.enconding = 'utf-8'
setcookie = response.headers['Set-Cookie']
p = r'JSESSIONID=([0-9A-Za-z]{1,})'
cookie = re.search(p, setcookie).group(1)
p = r'<input type="hidden" id="lt" name="lt" value="(LT-\d{1,}-[0-9A-Za-z]{1,}-cas)" />'
lt = re.search(p, response.text).group(1)
p = r'<input type="hidden" name="execution" value="([0-9A-Za-z]{1,})" />'
execu = re.search(p, response.text).group(1)
return lt, execu, cookie
def to_node(self, lt, upwd):
response = requests.get(
'http://127.0.0.1:2022/?lt={0}&upwd={1}'.format(lt, upwd)).text
return response
def checkin(self, rsa, lt, execu, cookie_1, user, code,passwd):
url_1 = 'https://cas.hdu.edu.cn/cas/login?state=IFgP7G0QAG0UFHop0M4&service=https%3A%2F%2Fskl.hdu.edu.cn%2Fapi%2Fcas%2Flogin%3Fstate%3DIFgP7G0QAG0UFHop0M4%26index%3D'
data_1 = {
'rsa': rsa,
'ul': len(user),
'pl': len(passwd),
'lt': lt,
'execution': execu,
'_eventId': 'submit'}
head_1 = {
'Host': 'cas.hdu.edu.cn',
'Origin': 'https://cas.hdu.edu.cn',
'Upgrade-Insecure-Requests': '1',
'Cookie': 'hdu_cas_un={0}; JSESSIONID={1}; Language=zh_CN'.format(user, cookie_1),
'Accept-Encoding': 'gzip, deflate',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
'Referer': 'https://cas.hdu.edu.cn/cas/login?state=IFgP7G0QAG0UFHop0M4&service=https%3A%2F%2Fskl.hdu.edu.cn%2Fapi%2Fcas%2Flogin%3Fstate%3DIFgP7G0QAG0UFHop0M4%26index%3D'}
res = requests.post(url_1, data=data_1,
headers=head_1, allow_redirects=False)
url_2 = res.headers['Location']
p = r'CASTGC=([^;]+)'
cookie_3 = re.search(p, res.headers['Set-Cookie']).group(1)
head_2 = {
'Host': 'skl.hdu.edu.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Upgrade-Insecure-Requests': '1',
'Referer': 'https://cas.hdu.edu.cn/',
'Accept-Language': 'zh-CN,zh;q=0.9'}
url_3 = requests.get(url_2, headers=head_2,
allow_redirects=False).headers['Location']
head_3 = {
'Host': 'cas.hdu.edu.cn',
'Upgrade-Insecure-Requests': '1',
'Cookie': 'CASTGC={0};JSESSIONID={1}; Language=zh_CN'.format(cookie_3, cookie_1),
'Accept-Encoding': 'gzip, deflate',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
'Referer': 'https://cas.hdu.edu.cn/'}
url_4 = requests.get(url_3, headers=head_3,
allow_redirects=False).headers['Location']
head_4 = {
'Host': 'skl.hdu.edu.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Upgrade-Insecure-Requests': '1',
'Referer': 'https://cas.hdu.edu.cn/',
'Accept-Language': 'zh-CN,zh;q=0.9'}
token = requests.get(url_4, headers=head_4,
allow_redirects=False).headers['X-Auth-Token']
t = int(time.time()*1000)
url_5 = 'https://skl.hdu.edu.cn/api/checkIn/code-check-in?userid={0}&code={1}&latitude=30.31958&longitude=120.3391&t={2}'.format(
user, code, t)
id = str(uuid.uuid1())
head_5 = {
'Host': 'skl.hdu.edu.cn',
'X-Auth-Token': token,
'Skl-Ticket': id,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Origin': 'https://skl.hduhelp.com',
'Referer': 'https://cas.hdu.edu.cn/',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Accept-Encoding': 'gzip, deflate'}
res = requests.get(url_5, headers=head_5).text
p = '\"msg\":\"(.+)\"'
msg = re.search(p, res).group(1)
return(msg)
def autocheck(self, message, user, passwd, group):
secret = []
secret = self.spider()
lt = secret[0]
execu = secret[1]
cookie = secret[2]
rsa = self.to_node(lt, user+passwd)
result = 'hdu账号为'+user+'的返回消息:' + \
self.checkin(rsa, lt, execu, cookie, user, message,passwd)
requests.get(
url='http://127.0.0.1:5700/send_group_msg?group_id={0}&message={1}'.format(group, result))
最后的checkin还涉及到了uuid和时间戳。
个人感觉并不会对uuid进行校验,毕竟只是近似于无法重复的数字
附上源码: https://github.com/taka250/auto_checkin_skl_hdu
Oauth的学习以及开发自助上课签到脚本的更多相关文章
- [iOS]关于零基础学习iOS开发的学习方法总结
关于零基础学习iOS开发的学习方法总结 最近很多零基础来参加蓝鸥培训的学生经常会问到一些学习方法的问题,就如下我自己见过的好的学习方法一起讨论一下. 蓝鸥iOS开发技术的学习路线图 程序员的主要工作是 ...
- 任务驱动,Winform VS WEB对比式学习.NET开发系列第一篇------身份证解析(不断更新的WEB版本及Winform版本源码)
一 本系列培训随笔适用人群 1. 软件开发初学者 2. 有志于转向Web开发的Winform程序员 3. 想了解桌面应用开发的Web程序员 二 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分 ...
- 任务驱动,学习.NET开发系列第2篇------单词统计
一 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分人学习软件开发技术是通过看书,看视频,听老师上课的方式.这些方式有一个共同点即按知识点进行讲解.比如拿c#编程为例,首先是讲解大量的基础概念 ...
- 任务驱动,对比式学习.NET开发系列之开篇------开源2个小框架(一个Winform框架,一个Web框架)
一 源码位置 1. Winform框架 2. web框架 二 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分人学习软件开发技术是通过看书,看视频,听老师上课的方式.这些方式有一个共同点即按知 ...
- 想学习Android开发
最近被别人说知识面窄,心里受伤了.准备学学Android开发,如果能在手机里运行自己写的app,那是多么high ~~~ Android开发需要看什么资料呢? 说明:本人一直从事windows下的C+ ...
- 从C#到Objective-C,循序渐进学习苹果开发(4)--代码块(block)和错误异常处理的理解
本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...
- 从C#到Objective-C,循序渐进学习苹果开发(3)--分类(category)和协议Protocal的理解
本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...
- 从C#到Objective-C,循序渐进学习苹果开发(2)--Objective-C和C#的差异
本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台开发苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验. 在上篇<从C#到 ...
- 【零基础学习iOS开发】【转载】
原文地址:http://www.cnblogs.com/mjios/archive/2013/04/24/3039357.html 本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开 ...
随机推荐
- kafka如何保证不重复消费又不丢失数据_Kafka写入的数据如何保证不丢失?
我们暂且不考虑写磁盘的具体过程,先大致看看下面的图,这代表了 Kafka 的核心架构原理. Kafka 分布式存储架构 那么现在问题来了,如果每天产生几十 TB 的数据,难道都写一台机器的磁盘上吗?这 ...
- httpRunner使用小结
1.每个系统可以给所有相关接口准备一份完整的主流程数据,这样就不用每执行一条用例就要先执行很多前置用例2.每条用例在设计之初,关于使用的前置数据,以及条件判断的数据值,以及设置的前提条件数据值,尽量保 ...
- Oracle SQL Developer.exe双击启动错误信息dll未找到
下载地址:https://www.oracle.com/tools/downloads/sqldev-downloads.html 官网相应的解决方法已经说明了
- Kafka 与传统 MQ 消息系统之间有三个关键区别?
(1).Kafka 持久化日志,这些日志可以被重复读取和无限期保留 (2).Kafka 是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过 复制数据提升容错能力和高可用性 (3).Kafk ...
- Java 有没有 goto?
goto 是 Java 中的保留字,在目前版本的 Java 中没有使用.(根据 James Gosling (Java 之父)编写的<The Java Programming Language& ...
- MyBatis Plus 2.3 个人笔记-03-Active Record
AR 语法糖 是一种领域模型模式,特点就是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一条记录 实现AR [在代码生成器中可以添加配置] import com.baomidou ...
- SpringCloud个人笔记-02-Feign初体验
项目结构 sb_cloud_product <?xml version="1.0" encoding="UTF-8"?> <project x ...
- 2. 使用Github
2. 使用Github 2.1 目的 借助github托管项目代码 2.2 基本概念 仓库(Repository) 仓库用来存放项目代码,每个项目对应一个仓库,多个开源项目则有多个仓库 收藏(Star ...
- window onerror 各浏览器下表现总结
window onerror 各浏览器下表现总结 做前端错误上报,必然离不开window onerror,但window onerror在不同设备上表现并不一致,浏览器为避免信息泄露,在一些情况下并不 ...
- 设计模式-观察者模式Observe的实现
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...