首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python内部错误login.html login.cgi

Python内部错误login.html login.cgi
EN

Stack Overflow用户
提问于 2021-02-01 10:52:12
回答 1查看 431关注 0票数 1

我目前正在尝试在页面中创建一个简单的登录到我使用Ubuntu在虚拟机上运行的实际本地网页。

我在/var/www/html位置创建了/var/www/html

然后,HTML调用/usr/lib/cgi-bin/login.cgi中的/usr/lib/cgi-bin/login.cgi文件。

我得到了一个Internal Server Error。这些日志基本上只显示了以下内容:

POST/cgi/login.cgi HTTP/1.1“500799 "http://localhost/LoginPage.html”Mozialla/5.0 (X11;Ubtuntu;Linux x86_64;rv:84.0) Geck/201000101 Firefox/84.0

HTML文件似乎按照预期工作,但是当我按下登录并被重定向到CGI文件时,我会得到CGI文件上的错误。我尝试删除CGI文件中的所有内容,只留下几行,但仍然会出现错误。

我的另一个项目-- cgi-bin文件夹中的文件仍然工作正常,没有错误。

代码语言:javascript
复制
<HTML>
<HEAD><TITLE>Login Page</TITLE></HEAD>
    <BODY>
        <CENTER>
        <FORM method="POST" action="/cgi-bin/login.cgi">
            <paragraph> Enter your login name: <input type="text" name="login">
            <paragraph> Enter your password: <input type=password name="password">
            <paragraph> <input type="submit" value="Connect">
        </FORM>
        </CENTER>
        <HR>

        </form>
    </BODY>
</HTML>
代码语言:javascript
复制
#!/usr/bin/python3
import sys
import cgi
import os
import cgitb

sys.path.insert(0,'/usr/lib/project_name')
def header():
    #print "Content-type: text/html\n"
    print("<HEAD>")
    print("<TITLE> title </TITLE>")
    print("</HEAD>")

def Log():
    print("<!DOCTYPE html>")
    print("<HTML>")
    print("<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">")
    print("  <meta charset=\"utf-8\" />")
    header()
    print("BODY")
    form = cgi.FieldStorage()
    login = "login"
    password = "test123"
    if not (form):
        header("Login Response")
        print("<BODY>")
    elsif (form.has_key("login") and form["login"].value == login and form.has_key("password") and form["password"].value == password):
        header("Connected ...")
        print("<BODY>")
        print("<center><hr><H3>Welcome back,\" , form[\"login\"].value, \".</H3><hr></center>")
        print("r\"\"\"<form><input type=\"hidden\" name=\"session\" value=\"%s\"></form>\"\"\" % (form[\"login\"].value)")
        print("<H3><a href=\"/cgi-bin/projects.cgi\">Click here to start browsing</a></H3>")
    else:
        header("No success!")
        print("<BODY>")
        print("<H3>Please go back and enter a valid login.</H3>")

def footer():
    print("</BODY>")
    print("</HTML>")

print("Content-type:text/html\r\n\r\n")
cgitb.enable()
Log()
footer()

编辑:

下面是解析error.logInternal Server Error的内容

(2)没有这样的文件或目录:‘/usr/lib/cgi/login.cgi’的执行失败:/usr/lib/cgi/ login.cgi,引用:http://localhost/LoginPage.html Tue Feb 02 08:40:41.199411 2021 pid 10292:tid 140490049578752

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-01 11:26:23

纠正设置:

没有这样的文件或目录:‘/usr/lib/cgi/login.cgi’的exec失败:/usr/lib/cgi/login.cgi,引用:http://localhost/LoginPage.html

确保CGI脚本及其父目录具有正确的权限:

代码语言:javascript
复制
chmod 755 /usr/lib/cgi-bin/ /usr/lib/cgi-bin/login.cgi

另外,CGI脚本可能有窗口行的结尾,所以请确保您也删除了它们,例如通过运行dos2unix login.cgi (更多细节请参见这个职位 )。

解决内部服务器错误:

首先,至少进行以下更改以更正语法(这就是导致Internal Server Error的原因):

  1. elsif应该是elif
  2. 您的header函数应该包含一个参数,即def header(title)
  3. 在有form.has_key的地方,将其更改为使用in,因为现在已不再推荐has_key,例如"password" in form而不是form.has_key("password")

修正后的情况如下:

代码语言:javascript
复制
elif "login" in form and form["login"].value == login and "password" in form and form["password"].value == password:

顺便说一句,坚持使用所有最新浏览器都支持的HTML5,现在已经不再推荐标签了(它已经不再像标签那样了)。使用CSS代替

此外,作为一个完整的旁注,这些天,很少看到所有大写的用于HTML。你在某些地方使用过这种风格,但我建议放弃使用小写标记名。

简化HTML生成:

除上述内容外,我建议使用F-字符串进行字符串格式化,并使用多行字符串来稍微简化逻辑。

下面是一些如何增强代码的示例。

您的头函数可能像建议的那样使用f字符串和多行字符串。title参数是可选的。

代码语言:javascript
复制
def header(title=""):
    print(f"""
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="utf-8">
            <title> {title} </title>
        </head>
        <body>
    """)

您的页脚函数可能如下所示:

代码语言:javascript
复制
def footer():
    print("""
        </body>
        </html>
    """)

最后,您的HTML表单可以如下所示,使用text-align: center;对中心进行调整:

代码语言:javascript
复制
print(f"""
    <hr>
        <h3 style="text-align: center;">Welcome back { form["login"].value }</h3>
    <hr>
    <form>
        <input type="hidden" name="session" value="{ form["login"].value }">
    </form>
    <h3>
        <a href="/cgi-bin/projects.cgi">Click here to start browsing</a>
    </h3>
""")

美化HTML:

为了进一步美化HTML,您可以使用import textwrap,然后使用textwrap.dedent()删除HTML中常见的前导空间(由于Python中的缩进)。

代码语言:javascript
复制
print(textwrap.dedent(f"""
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title> {title} </title>
    </head>
    <body>
"""))

这有两个好处:

  1. 在通过网络发送之前,它消除了不必要的前导空间--因此,您发送的数据较少,节省了带宽。
  2. 当您使用客户端浏览器检查HTML源代码时,它会更漂亮一些--这对于调试非常有用。

或者,使用HTML模板:

进一步的增强是使用HTML模板框架,例如Jinja2。这将允许您将HTML存储到文件中,然后通过传递变量来呈现HTML文件。

这样,Python代码就会变得简单得多。您只需呈现模板并传递所需的变量。例如,对于您的标题,可以如下所示:

代码语言:javascript
复制
template = env.get_template('header.html')
print(template.render(title='Connected ...'))

您需要像这样首先设置Environment

代码语言:javascript
复制
from jinja2 import Environment

env = Environment(
    loader=PackageLoader('package', 'templates')
    autoescape=select_autoescape(['html'])
)

并将您的header.html文件放在一个名为templates的目录中。

您可能还想了解https://en.wikipedia.org/wiki/Separation_of_concerns原理和MVC架构。使用这样的模板离实现MVC只是一步之遥。

关于安全的最后一点:

看起来,您正在使用HTML用户名字段来存储用户名,并将其视为会话令牌。我是高度不安全,不会缩放。不过,这可能对你的目的来说已经足够了。对其进行改进的一个简单方法是使用标题将其存储为cookie,并使其成为HttpOnly

代码语言:javascript
复制
Set-cookie: session=value; HttpOnly

其中value可以是一些唯一的令牌(例如,一个uuid)。

这比你现在的方法要好得多。

但是,更好的是,您可以使用像PyJWT这样的库来实现安全性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65991370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档