mirror of
https://codeberg.org/mayx/pages
synced 2026-02-16 01:54:50 +08:00
update
This commit is contained in:
458
2023/08/01/auth.html
Normal file
458
2023/08/01/auth.html
Normal file
@@ -0,0 +1,458 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||
<title>如何让Python脚本接收OAuth2.0的Code? | Mayx的博客</title>
|
||||
<meta name="generator" content="Jekyll v3.9.5" />
|
||||
<meta property="og:title" content="如何让Python脚本接收OAuth2.0的Code?" />
|
||||
<meta name="author" content="mayx" />
|
||||
<meta property="og:locale" content="zh_CN" />
|
||||
<meta name="description" content="越简单,就越复杂。" />
|
||||
<meta property="og:description" content="越简单,就越复杂。" />
|
||||
<meta property="og:site_name" content="Mayx的博客" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="article:published_time" content="2023-08-01T00:00:00+08:00" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta property="twitter:title" content="如何让Python脚本接收OAuth2.0的Code?" />
|
||||
<meta name="google-site-verification" content="huTYdEesm8NaFymixMNqflyCp6Jfvd615j5Wq1i2PHc" />
|
||||
<meta name="msvalidate.01" content="0ADFCE64B3557DC4DC5F2DC224C5FDDD" />
|
||||
<meta name="yandex-verification" content="fc0e535abed800be" />
|
||||
<script type="application/ld+json">
|
||||
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"mayx"},"dateModified":"2023-08-01T00:00:00+08:00","datePublished":"2023-08-01T00:00:00+08:00","description":"越简单,就越复杂。","headline":"如何让Python脚本接收OAuth2.0的Code?","mainEntityOfPage":{"@type":"WebPage","@id":"/2023/08/01/auth.html"},"publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"https://avatars0.githubusercontent.com/u/17966333"},"name":"mayx"},"url":"/2023/08/01/auth.html"}</script>
|
||||
<!-- End Jekyll SEO tag -->
|
||||
|
||||
<link rel="canonical" href="https://mabbs.github.io/2023/08/01/auth.html" />
|
||||
<link type="application/atom+xml" rel="alternate" href="/atom.xml" title="Mayx的博客" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Mayx的博客(RSS)" href="/rss.xml" />
|
||||
<link rel="alternate" type="application/json" title="Mayx的博客(JSON Feed)" href="/feed.json" />
|
||||
<link rel="stylesheet" href="/assets/css/style.css?v=1770803700" />
|
||||
<!--[if !IE]> -->
|
||||
<link rel="stylesheet" href="/Live2dHistoire/live2d/css/live2d.css" />
|
||||
<!-- <![endif]-->
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Mayx的博客" />
|
||||
<link rel="webmention" href="https://webmention.io/mabbs.github.io/webmention" />
|
||||
<link rel="pingback" href="https://webmention.io/mabbs.github.io/xmlrpc" />
|
||||
<link rel="preconnect" href="https://summary.mayx.eu.org" crossorigin="anonymous" />
|
||||
<link rel="prefetch" href="https://www.blogsclub.org/badge/mabbs.github.io" as="image" />
|
||||
<link rel="blogroll" type="text/xml" href="/blogroll.opml" />
|
||||
<link rel="me" href="https://github.com/Mabbs" />
|
||||
<script src="/assets/js/jquery.min.js"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<script>
|
||||
var lastUpdated = new Date("Wed, 11 Feb 2026 17:55:00 +0800");
|
||||
var BlogAPI = "https://summary.mayx.eu.org";
|
||||
</script>
|
||||
<script src="/assets/js/main.js"></script>
|
||||
<!--[if !IE]> -->
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-137710294-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-137710294-1');
|
||||
</script>
|
||||
|
||||
<script src="/assets/js/instant.page.js" type="module"></script>
|
||||
<!-- <![endif]-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--[if !IE]> --><noscript><marquee style="top: -15px; position: relative;"><small>发现当前浏览器没有启用JavaScript,这不影响你的浏览,但可能会有一些功能无法使用……</small></marquee></noscript><!-- <![endif]-->
|
||||
<!--[if IE]><marquee style="top: -15px; position: relative;"><small>发现当前浏览器为Internet Explorer,这不影响你的浏览,但可能会有一些功能无法使用……</small></marquee><![endif]-->
|
||||
<div class="wrapper">
|
||||
<header class="h-card">
|
||||
<h1><a class="u-url u-uid p-name" rel="me" href="/">Mayx的博客</a></h1>
|
||||
|
||||
|
||||
<img src="https://avatars0.githubusercontent.com/u/17966333" fetchpriority="high" class="u-photo" alt="Logo" style="width: 90%; max-width: 300px; max-height: 300px;" />
|
||||
|
||||
|
||||
<p class="p-note">Mayx's Home Page</p>
|
||||
|
||||
<form action="/search.html">
|
||||
<input type="text" name="keyword" id="search-input-all" placeholder="Search blog posts.." /> <input type="submit" value="搜索" />
|
||||
</form>
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="view"><a class="u-url" href="/Mabbs/">About me</a></p>
|
||||
|
||||
<ul class="downloads">
|
||||
|
||||
<li style="width: 270px; border-right: none;"><a href="/MayxBlog.tgz">Download <strong>TGZ File</strong></a></li>
|
||||
|
||||
</ul>
|
||||
</header>
|
||||
<section class="h-entry">
|
||||
|
||||
<small><time class="date dt-published" datetime="2023-08-01T00:00:00+08:00">1 August 2023</time> - 字数统计:3672 - 阅读大约需要12分钟 - Hits: <span id="/2023/08/01/auth.html" class="visitors">Loading...</span></small>
|
||||
<h1 class="p-name">如何让Python脚本接收OAuth2.0的Code?</h1>
|
||||
|
||||
<p class="view">by <a class="p-author h-card" href="//github.com/Mabbs">mayx</a></p>
|
||||
<div id="outdate" style="display:none;">
|
||||
<hr /><p>
|
||||
这是一篇创建于 <span id="outime"></span> 天前的文章,其中的信息可能已经有所发展或是发生改变。
|
||||
</p>
|
||||
</div>
|
||||
<script>
|
||||
daysold = Math.floor((new Date().getTime() - new Date("Tue, 01 Aug 2023 00:00:00 +0800").getTime()) / (24 * 60 * 60 * 1000));
|
||||
if (daysold > 90) {
|
||||
document.getElementById("outdate").style.display = "block";
|
||||
document.getElementById("outime").innerHTML = daysold;
|
||||
}
|
||||
</script>
|
||||
|
||||
<hr />
|
||||
|
||||
<b>AI摘要</b>
|
||||
<p id="ai-output">这篇文章讨论了在Windows环境下,让Python脚本接收OAuth2.0授权码Code的几种方法。作者尝试了以下几种方式:
|
||||
|
||||
1. **URI Scheme**: 通过注册伪协议(如mayx://)并在Python脚本中解析回调URL来获取Code,但这种方法可能被杀毒软件阻拦,且不是所有平台都支持。
|
||||
|
||||
2. **HTTP服务监听**: 使用Flask创建一个简单的web服务来接收Code,虽然简单但可能占用过多资源,且已被弃用。
|
||||
|
||||
3. **Socket实现**: 用socket进行TCP连接来处理请求,但初次访问时有问题,且代码复杂。
|
||||
|
||||
4. **http.server模块**: 使用Python内置的HTTP服务器模块实现了基本功能,更小且稳定,但仍有程序结束前端口未释放的问题,后来通过AI得到了解决。
|
||||
|
||||
作者在寻找最合适的方案时遇到困难,感慨了解更多信息有时也带来困扰,但最终还是AI有效地解决了问题。</p>
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
|
||||
<ul><li><a href="#起因">起因</a></li><li><a href="#解决方法">解决方法</a><ul><li><a href="#1-使用uri-scheme">1. 使用URI Scheme</a></li><li><a href="#2-使用http服务监听">2. 使用http服务监听</a><ul><li><a href="#使用flask实现">使用Flask实现</a></li><li><a href="#使用socket实现">使用socket实现</a></li><li><a href="#使用httpserver实现">使用http.server实现</a></li></ul></li></ul></li><li><a href="#感想">感想</a></li></ul>
|
||||
<hr />
|
||||
|
||||
|
||||
<main class="post-content e-content" role="main"><p>越简单,就越复杂。<!--more--></p>
|
||||
<h1 id="起因">
|
||||
|
||||
|
||||
<a href="#起因"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 起因
|
||||
|
||||
|
||||
</h1>
|
||||
|
||||
<p>最近我在写一个在Windows上运行的Python脚本,需要做一个类似于第三方登录的功能。一般来说像这种东西都是使用的OAuth2.0来做认证,我接入的平台没有悬念的也是使用的这个东西,其中的重点就是获取到第三方网站的授权码Code,然后用它换取用户信息。于是我就在想怎么做比较好呢?</p>
|
||||
<h1 id="解决方法">
|
||||
|
||||
|
||||
<a href="#解决方法"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 解决方法
|
||||
|
||||
|
||||
</h1>
|
||||
|
||||
<h2 id="1-使用uri-scheme">
|
||||
|
||||
|
||||
<a href="#1-使用uri-scheme"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 1. 使用URI Scheme
|
||||
|
||||
|
||||
</h2>
|
||||
|
||||
<p>我看VSCode在实现类似功能的时候似乎用到了URI Scheme,就是在系统中注册一个伪协议,然后通过这个伪协议来调用程序实现获取Code,方法很简单,首先先在注册表里导入:</p>
|
||||
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Windows</span> <span class="err">Registry</span> <span class="err">Editor</span> <span class="err">Version</span> <span class="err">5.00</span>
|
||||
|
||||
<span class="nn">[HKEY_CLASSES_ROOT\mayx]</span>
|
||||
<span class="err">"URL</span> <span class="err">Protocol"="D:\\mayx.exe"</span>
|
||||
<span class="err">@="MayxProtocol"</span>
|
||||
|
||||
<span class="nn">[HKEY_CLASSES_ROOT\mayx\DefaultIcon]</span>
|
||||
<span class="err">@="D:\\mayx.exe,1"</span>
|
||||
|
||||
<span class="nn">[HKEY_CLASSES_ROOT\mayx\shell]</span>
|
||||
|
||||
<span class="nn">[HKEY_CLASSES_ROOT\mayx\shell\open]</span>
|
||||
|
||||
<span class="nn">[HKEY_CLASSES_ROOT\mayx\shell\open\command]</span>
|
||||
<span class="err">@="\"D:\\mayx.exe\"</span> <span class="err">\"%1\""</span>
|
||||
</code></pre></div></div>
|
||||
<p>然后编写一个Python脚本并用Pyinstaller打包:</p>
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
||||
</code></pre></div></div>
|
||||
<p>最后将回调地址填为“mayx://get”,这样认证完成之后就会像这样调用程序:“D:\mayx.exe mayx://get?code=something”,再用urllib简单做个解析就完成了。 </p><p>
|
||||
这样看起来是不是非常的简单?看起来确实是挺简单的,可惜坑比较大,第一个是像上述这样的注册表有些杀毒软件会拒绝导入,因为像“shell\open\command”这种东西被病毒啥的滥用的地方太多了,除非软件通过了数字签名或者某些认证,否则正常情况下根本没法导入。二是不是所有的第三方平台都支持伪协议的方式调用,不过我试了一下我用的那个平台倒是支持😂,除了杀毒软件比较讨厌之外其他的倒还好。</p>
|
||||
<h2 id="2-使用http服务监听">
|
||||
|
||||
|
||||
<a href="#2-使用http服务监听"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 2. 使用http服务监听
|
||||
|
||||
|
||||
</h2>
|
||||
|
||||
<p>很多跨平台的程序,像有些主要在Linux上运行的某些程序就喜欢在获取Code的时候启动一个简单的web服务。其实用这个方法的话可能还更方便一点,不容易出问题。</p>
|
||||
<h3 id="使用flask实现">
|
||||
|
||||
|
||||
<a href="#使用flask实现"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 使用Flask实现
|
||||
|
||||
|
||||
</h3>
|
||||
|
||||
<p>最开始,我想着要不然就用Flask来实现这个功能吧,实现起来也简单,写起来就几行:</p>
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">request</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="s">""</span>
|
||||
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>
|
||||
<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/getcode'</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">get</span><span class="p">():</span>
|
||||
<span class="k">global</span> <span class="n">code</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"code"</span><span class="p">)</span>
|
||||
<span class="n">shutdown</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">environ</span><span class="p">[</span><span class="s">"werkzeug.server.shutdown"</span><span class="p">]</span>
|
||||
<span class="n">shutdown</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="s">"OK"</span>
|
||||
|
||||
<span class="n">app</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s">"127.0.0.1"</span><span class="p">,</span><span class="n">port</span><span class="o">=</span><span class="mi">8000</span><span class="p">)</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
|
||||
</code></pre></div></div>
|
||||
<p>看起来也确实很简单,功能实现的也很完美,但是有个问题是总感觉用Flask做这么简单的事情实在是大材小用,打包成程序也要占不少空间,另外就是这个方法已经被弃用了,感觉就是很不爽。那要说不爽的话怎么才爽呢?</p>
|
||||
<h3 id="使用socket实现">
|
||||
|
||||
|
||||
<a href="#使用socket实现"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 使用socket实现
|
||||
|
||||
|
||||
</h3>
|
||||
|
||||
<p>我想起来之前期末时写的期末作业<a href="https://github.com/Mabbs/socket-bbs">socket-bbs</a>,这就是用socket实现的一个简单的论坛,那我这么简单的功能想来用socket实现不是很好吗?于是就写了一个:(这段代码没有测试,因为这个方法不能用所以把代码删了,这是重新做的)</p>
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">socket</span>
|
||||
<span class="kn">import</span> <span class="nn">urllib.parse</span>
|
||||
<span class="n">server</span> <span class="o">=</span> <span class="n">socket</span><span class="p">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="p">.</span><span class="n">AF_INET</span><span class="p">,</span><span class="n">socket</span><span class="p">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> <span class="c1">#打开一个网络连接
|
||||
</span><span class="n">server</span><span class="p">.</span><span class="n">bind</span><span class="p">((</span><span class="s">'127.0.0.1'</span><span class="p">,</span><span class="mi">8000</span><span class="p">))</span> <span class="c1">#绑定要监听的端口
|
||||
</span><span class="n">server</span><span class="p">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># 设置最大的连接数量为5
|
||||
</span><span class="n">code</span> <span class="o">=</span> <span class="s">""</span>
|
||||
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
|
||||
<span class="n">sock</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">server</span><span class="p">.</span><span class="n">accept</span><span class="p">()</span> <span class="c1"># 建立客户端连接
|
||||
</span> <span class="n">data</span> <span class="o">=</span> <span class="n">sock</span><span class="p">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">8192</span><span class="p">).</span><span class="n">decode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">).</span><span class="n">split</span><span class="p">(</span><span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">)</span><span class="c1">#接收TCP数据,数据以字符串的形式返还
|
||||
</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># 关闭连接
|
||||
</span> <span class="k">continue</span>
|
||||
<span class="n">url</span> <span class="o">=</span> <span class="n">urllib</span><span class="p">.</span><span class="n">parse</span><span class="p">.</span><span class="n">urlparse</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">split</span><span class="p">()[</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="k">if</span> <span class="n">url</span><span class="p">.</span><span class="n">path</span> <span class="o">==</span> <span class="s">'/getcode'</span><span class="p">:</span>
|
||||
<span class="n">query</span> <span class="o">=</span> <span class="n">urllib</span><span class="p">.</span><span class="n">parse</span><span class="p">.</span><span class="n">parse_qs</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">data</span><span class="p">)</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="n">query</span><span class="p">[</span><span class="s">"code"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">((</span><span class="s">"HTTP/1.0 200 OK"</span> <span class="o">+</span> <span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">((</span><span class="s">"Content-Type: text/html; charset=utf-8"</span> <span class="o">+</span> <span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="s">"OK"</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span> <span class="c1">#发送TCP数据
|
||||
</span> <span class="n">sock</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># 关闭连接
|
||||
</span> <span class="k">break</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">((</span><span class="s">"HTTP/1.0 404 Not Found"</span> <span class="o">+</span> <span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">((</span><span class="s">"Content-Type: text/html; charset=utf-8"</span> <span class="o">+</span> <span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="s">'</span><span class="se">\r\n</span><span class="s">'</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
|
||||
<span class="n">sock</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="s">"Not Found"</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span> <span class="c1">#发送TCP数据
|
||||
</span> <span class="n">sock</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># 关闭连接
|
||||
</span><span class="k">print</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
|
||||
</code></pre></div></div>
|
||||
<p>看起来是不是复杂多了?其实大多数时候工作的好像挺正常的,但是不知道为什么莫名其妙第一次访问的时候会卡住,改了半天头都大了,于是就只好放弃这种方法了……</p>
|
||||
<h3 id="使用httpserver实现">
|
||||
|
||||
|
||||
<a href="#使用httpserver实现"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 使用http.server实现
|
||||
|
||||
|
||||
</h3>
|
||||
|
||||
<p>这时候我突然想到我平时用来传文件用的python自带的模块http.server,既然这个模块是自带的,大小应该大不到哪去吧?随后我就写了一个:</p>
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">http.server</span> <span class="kn">import</span> <span class="n">BaseHTTPRequestHandler</span><span class="p">,</span> <span class="n">ThreadingHTTPServer</span>
|
||||
<span class="kn">import</span> <span class="nn">urllib.parse</span>
|
||||
<span class="n">code</span> <span class="o">=</span> <span class="s">""</span>
|
||||
<span class="k">class</span> <span class="nc">Resquest</span><span class="p">(</span><span class="n">BaseHTTPRequestHandler</span><span class="p">):</span>
|
||||
<span class="n">timeout</span> <span class="o">=</span> <span class="mi">5</span>
|
||||
<span class="k">def</span> <span class="nf">do_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">url</span> <span class="o">=</span> <span class="n">urllib</span><span class="p">.</span><span class="n">parse</span><span class="p">.</span><span class="n">urlparse</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">path</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">url</span><span class="p">.</span><span class="n">path</span> <span class="o">==</span> <span class="s">"/getuser"</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">"Content-type"</span><span class="p">,</span> <span class="s">"text/html"</span><span class="p">)</span> <span class="c1"># 设置服务器响应头
|
||||
</span> <span class="n">code</span> <span class="o">=</span> <span class="n">urllib</span><span class="p">.</span><span class="n">parse</span><span class="p">.</span><span class="n">parse_qs</span><span class="p">(</span><span class="n">url</span><span class="p">.</span><span class="n">query</span><span class="p">)[</span><span class="s">"code"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="n">buf</span> <span class="o">=</span> <span class="s">'''OK'''</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">wfile</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">buf</span><span class="p">.</span><span class="n">encode</span><span class="p">())</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">server</span><span class="p">.</span><span class="n">shutdown</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">"Content-type"</span><span class="p">,</span> <span class="s">"text/html"</span><span class="p">)</span> <span class="c1"># 设置服务器响应头
|
||||
</span> <span class="bp">self</span><span class="p">.</span><span class="n">end_headers</span><span class="p">()</span>
|
||||
<span class="n">buf</span> <span class="o">=</span> <span class="s">'''Not Found'''</span>
|
||||
<span class="bp">self</span><span class="p">.</span><span class="n">wfile</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">buf</span><span class="p">.</span><span class="n">encode</span><span class="p">())</span>
|
||||
<span class="n">host</span> <span class="o">=</span> <span class="p">(</span><span class="s">"127.0.0.1"</span><span class="p">,</span> <span class="mi">8000</span><span class="p">)</span>
|
||||
<span class="n">server</span> <span class="o">=</span> <span class="n">ThreadingHTTPServer</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">Resquest</span><span class="p">)</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="s">"Starting server, listen at: %s:%s"</span> <span class="o">%</span> <span class="n">host</span><span class="p">)</span>
|
||||
<span class="n">server</span><span class="p">.</span><span class="n">serve_forever</span><span class="p">()</span>
|
||||
<span class="n">server</span><span class="p">.</span><span class="n">socket</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
|
||||
</code></pre></div></div>
|
||||
<p>最后打包试了一下,功能正常,虽然还是大了点,不过比Flask小😁。其实我在写这个代码的时候,最开始不知道要在最后加上<code class="language-plaintext highlighter-rouge">server.socket.close()</code>,一开始写的时候总是遇到程序执行完之前端口必定不会释放,令人很烦,直接搜也没什么好的结果,不过问了下ChatGPT立马就解决了🤣,它说:</p>
|
||||
<blockquote>
|
||||
<p>当你调用<code class="language-plaintext highlighter-rouge">server.shutdown()</code>来停止服务器时,它会停止接收新的连接,并关闭已有的连接。但是,由于Python的socket库的设计,socket对象并不会立即释放端口。相反,它会在一段时间内处于TIME_WAIT状态,以确保在网络中所有挂起的数据都被正确传递或丢弃。这是一种网络协议的要求,称为”TCP TIME_WAIT”状态。</p>
|
||||
</blockquote>
|
||||
|
||||
<p>AI还真是方便啊……</p>
|
||||
<h1 id="感想">
|
||||
|
||||
|
||||
<a href="#感想"><svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg></a> 感想
|
||||
|
||||
|
||||
</h1>
|
||||
|
||||
<p>解决这么一个小问题却一时半会拿不下最合适的方案,这难道就是了解太多的副作用吗😝,不过最终来看还是AI厉害,一下子就解决了我的问题。</p></main>
|
||||
|
||||
|
||||
<small style="display: block">tags: <a rel="category tag" class="p-category" href="/search.html?keyword=Python"><em>Python</em></a> - <a rel="category tag" class="p-category" href="/search.html?keyword=%E6%9C%8D%E5%8A%A1%E5%99%A8"><em>服务器</em></a> - <a rel="category tag" class="p-category" href="/search.html?keyword=OAuth"><em>OAuth</em></a> <span style="float: right;"><a href="https://gitlab.com/mayx/mayx.gitlab.io/tree/master/_posts/2023-08-01-auth.md">查看原始文件</a></span></small>
|
||||
|
||||
|
||||
<h4 style="border-bottom: 1px solid #e5e5e5;margin: 2em 0 5px;">推荐文章</h4>
|
||||
<p id="suggest-container">Loading...</p>
|
||||
<script>
|
||||
var suggest = $("#suggest-container");
|
||||
$.get(BlogAPI + "/suggest?id=/2023/08/01/auth.html&update=" + lastUpdated.valueOf(), function (data) {
|
||||
if (data.length) {
|
||||
getSearchJSON(function (search) {
|
||||
suggest.empty();
|
||||
var searchMap = {};
|
||||
for (var i = 0; i < search.length; i++) {
|
||||
searchMap[search[i].url] = search[i];
|
||||
}
|
||||
|
||||
var tooltip = $('<div class="content-tooltip"></div>').appendTo('body').hide();
|
||||
for (var j = 0; j < data.length; j++) {
|
||||
var item = searchMap[data[j].id];
|
||||
if (item) {
|
||||
var link = $('<a href="' + item.url + '">' + item.title + '</a>');
|
||||
var contentPreview = item.content.substring(0, 100);
|
||||
if (item.content.length > 100) {
|
||||
contentPreview += "……";
|
||||
}
|
||||
link.hover(
|
||||
function(e) {
|
||||
tooltip.text($(this).data('content'))
|
||||
.css({
|
||||
top: e.pageY + 10,
|
||||
left: e.pageX + 10
|
||||
})
|
||||
.show();
|
||||
},
|
||||
function() {
|
||||
tooltip.hide();
|
||||
}
|
||||
).mousemove(function(e) {
|
||||
tooltip.css({
|
||||
top: e.pageY + 10,
|
||||
left: e.pageX + 10
|
||||
});
|
||||
}).data('content', contentPreview);
|
||||
|
||||
suggest.append(link);
|
||||
suggest.append(' - ' + item.date + '<br />');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
suggest.html("暂无推荐文章……");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<br />
|
||||
<div class="pagination">
|
||||
|
||||
<span class="prev">
|
||||
<a href="/2023/07/09/bitmo.html">
|
||||
上一篇:分享一种无人值守的新型诈骗手段
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<br />
|
||||
|
||||
<span class="next">
|
||||
<a href="/2023/09/06/satellite.html">
|
||||
下一篇:关于卫星通信的一些看法
|
||||
</a>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<!--[if !IE]> -->
|
||||
<link rel="stylesheet" href="/assets/css/gitalk.css">
|
||||
<script src="/assets/js/gitalk.min.js"></script>
|
||||
|
||||
<div id="gitalk-container"></div>
|
||||
|
||||
<script>
|
||||
var gitalk = new Gitalk({
|
||||
clientID: '36557aec4c3cb04f7ac6',
|
||||
clientSecret: 'ac32993299751cb5a9ba81cf2b171cca65879cdb',
|
||||
repo: 'mabbs.github.io',
|
||||
owner: 'Mabbs',
|
||||
admin: ['Mabbs'],
|
||||
id: '/2023/08/01/auth', // Ensure uniqueness and length less than 50
|
||||
distractionFreeMode: false, // Facebook-like distraction free mode
|
||||
proxy: "https://cors-anywhere.mayx.eu.org/?https://github.com/login/oauth/access_token"
|
||||
})
|
||||
gitalk.render('gitalk-container')
|
||||
</script>
|
||||
<!-- <![endif]-->
|
||||
|
||||
</section>
|
||||
<!--[if !IE]> -->
|
||||
<div id="landlord" style="left:5px;bottom:0px;">
|
||||
<div class="message" style="opacity:0"></div>
|
||||
<canvas id="live2d" width="500" height="560" class="live2d"></canvas>
|
||||
<div class="live_talk_input_body">
|
||||
<form id="live_talk_input_form">
|
||||
<div class="live_talk_input_name_body" >
|
||||
<input type="checkbox" id="load_this" />
|
||||
<input type="hidden" id="post_id" value="/2023/08/01/auth.html" />
|
||||
<label for="load_this">
|
||||
<span style="font-size: 11px; color: #fff;"> 想问这篇文章</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="live_talk_input_text_body">
|
||||
<input name="talk" type="text" class="live_talk_talk white_input" id="AIuserText" autocomplete="off" placeholder="要和我聊什么呀?" />
|
||||
<button type="submit" class="live_talk_send_btn" id="talk_send">发送</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<input name="live_talk" id="live_talk" value="1" type="hidden" />
|
||||
<div class="live_ico_box" style="display:none;">
|
||||
<div class="live_ico_item type_info" id="showInfoBtn"></div>
|
||||
<div class="live_ico_item type_talk" id="showTalkBtn"></div>
|
||||
<div class="live_ico_item type_music" id="musicButton"></div>
|
||||
<div class="live_ico_item type_youdu" id="youduButton"></div>
|
||||
<div class="live_ico_item type_quit" id="hideButton"></div>
|
||||
<input name="live_statu_val" id="live_statu_val" value="0" type="hidden" />
|
||||
<audio src="" style="display:none;" id="live2d_bgm" data-bgm="0" preload="none"></audio>
|
||||
<input id="duType" value="douqilai" type="hidden" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="open_live2d">召唤伊斯特瓦尔</div>
|
||||
<!-- <![endif]-->
|
||||
<footer>
|
||||
<p>
|
||||
<small>Made with ❤ by Mayx<br />Last updated at 2026-02-11 17:55:00<br /> 总字数:617672 - 文章数:179 - <a href="/atom.xml" >Atom</a> - <a href="/README.html" >About</a></small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="/assets/js/scale.fix.js"></script>
|
||||
<!--[if !IE]> -->
|
||||
<script src="/assets/js/main_new.js"></script>
|
||||
<script src="/Live2dHistoire/live2d/js/live2d.js"></script>
|
||||
<script src="/Live2dHistoire/live2d/js/message.js"></script>
|
||||
<!-- <![endif]-->
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user