Нет секретного ключа ... Я полагаю, это было что-то еще - PullRequest
0 голосов
/ 11 июля 2020

Я создаю приложение для чата, используя Flask / Socketio / Javascript, и когда я разрабатываю функцию «создать канал» и когда приложение запускается, оно говорит: RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret..

Я видел другие темы, связанные с "секретным ключом", но во-первых: я не разместил объявление secret_key где-то странно, а во-вторых: я не забыл добавить app.config['SESSION_TYPE'], так как это то место, где я споткнулся в прошлый раз.

Я решил проблема была связана с функцией flash, так как когда я ее удалил, все работает. Есть ли способ отправить sh сообщение, но не получить сообщение об ошибке?

Мой код: application.py

import os
import requests

from flask import Flask, jsonify, render_template, request, redirect, url_for, flash
from flask_socketio import SocketIO, emit, join_room, leave_room

app = Flask(__name__)
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY")
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_PERMANENT']= False
socketio = SocketIO(app)
channels = {"1":0,"2":0,"3":0}

@app.route("/")
def home():
    return render_template('home.html', channels = channels)

@app.route("/chat")
def chat():
    username = request.args.get('username')
    channel_id = request.args.get("channel_id")
    if username and channel_id:
        channels[channel_id] +=1
        return render_template("index.html", username=username, channel_id=channel_id)
    print("Wait")
    return redirect(url_for('home'))

@app.route("/create")
def make_channel():
    channel_name = request.args.get("channel_name")
    if channel_name and not str.isspace(channel_name):
        channels[channel_name] = 0
        flash("Channel created!")
        return redirect(url_for('home'))
    flash('You have not filled in the channel name!')
    return render_template('home.html', channels=channels)

@socketio.on('join_room')
def join_room_event(data):
    app.logger.info("{} has joined channel {}. ".format(data['username'], data['channel']))
    join_room(data['channel'])
    socketio.emit('joined_room', data)

@socketio.on('leave_room')
def leave_room_event(data):
    app.logger.info("{} has left channel {}.".format(data['username'], data['channel']))
    leave_room(data['channel'])
    socketio.emit('left_room', data)
    channel_id = data['channel']
    channels[channel_id] -= 1


@socketio.on("send")
def vote(data):
    emit("announce message", data, broadcast=True)


if __name__ == '__main__':
    app.run(debug=True)

home.html

<!DOCTYPE HTML>
<html>
    <head>
        <title>Hello, world!</title>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
        {% if message != () %}
        <h4 class="text-danger">{{ message }}</h4>
        {% endif %}
        <form action="{{ url_for('chat') }}">
            <div>
                <label>Enter your name:</label>
                <label>
                    <input type="text" name="username">
                </label>
            </div>
            <div>
                <label>Enter Channel ID:</label>
                <select name="channel_id">
                    {% for channel in channels %}
                    <option value="{{ channel }}">{{ channel }} --- {{ channels[channel] }} users online</option>
                    {% endfor %}
                </select>
            </div>
            <button type="submit">Enter Room</button>
        </form>
        <form action="{{ url_for('make_channel') }}">
            <label>Enter Channel Name:</label>
            <label>
                <input type="text" name="channel_name">
            </label>
            <button type="submit">Create Channel</button>
        </form>
        <script>
            document.addEventListener('DOMContentLoaded')
        </script>
    </body>
</html>

index.html Примечание: я знаю, что не следует помещать javascript и HTML в один файл, поэтому не говори об этом.

<!DOCTYPE html>
<html lang="en">
    <head>
        <script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
        <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
        <script>
            document.addEventListener('DOMContentLoaded', () => {

                // Connect to websocket
                var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);

                socket.on('connect', () => {
                    socket.emit('join_room', {
                        'username': "{{ username }}",
                        'channel': '{{ channel_id }}'
                    })
                });

                // The button should emit the value of the textbox
                document.getElementById('send').onclick = e => {
                    e.preventDefault();
                    let message_input = document.getElementById('textbox');
                    const message = message_input.value.trim();
                    if(message.length){
                        socket.emit('send', {
                            'message': message,
                            'username': "{{ username }}",
                            'channel': "{{ channel_id }}"
                        });
                    }
                    message_input.value = '';
                    message_input.focus();

                };

                document.getElementById('leave').onclick = () =>{
                    const data = {
                        'username': '{{ username }}',
                        'channel': '{{ channel_id }}'
                    };
                    socket.emit('leave_room', data);
                    window.location.href = "{{ url_for('home') }}";

                };

                socket.on('left_room', data =>{
                    if (data.channel === "{{ channel_id }}"){
                        const inner = document.createElement('div');
                        inner.innerHTML = `<b>${data.username}</b> has left the room.`;
                        inner.style.backgroundColor = "#e1f3fb";
                        inner.style.fontFamily = "sans-serif";
                        inner.style.fontSize = "12px";
                        inner.style.borderColor = "#d5cec7";
                        inner.className = "rounded";
                        inner.style.display= "inline-block";
                        inner.style.border= '2px solid #d5cec7';
                        const div = document.createElement('div');
                        div.appendChild(inner);
                        div.style.width = "100%";
                        document.getElementById('message').appendChild(div);
                    }
                });


                socket.on('joined_room', data => {
                    if (data.channel === "{{ channel_id }}"){
                        const inner  = document.createElement('div');
                        if (data.username !== "{{ username }}"){
                            console.log('not me.');
                            inner.innerHTML = `<b>${data.username}</b> has joined the channel!`;
                        } else {
                            console.log('me.');
                            inner.innerHTML = `<b>You</b> joined the channel.`;
                        }
                        inner.style.backgroundColor = "#e1f3fb";
                        inner.style.fontFamily = "sans-serif";
                        inner.style.fontSize = "12px";
                        inner.style.borderColor = "#d5cec7";
                        inner.className = "rounded";
                        inner.style.display= "inline-block";
                        inner.style.border= '2px solid #d5cec7';
                        const div = document.createElement('div');
                        div.appendChild(inner);
                        div.style.width = "100%";
                        document.getElementById('message').appendChild(div);
                    }
                });

                socket.on('announce message', data => {
                    console.log(data.channel);
                    console.log("{{ channel_id }}");
                    if (data.channel === "{{ channel_id }}") {
                        const inner = document.createElement('div');
                        const div = document.createElement('div');
                        inner.innerHTML = `${data.username}: ${data.message}`;
                        inner.style.fontFamily = "sans-serif";
                        inner.style.fontSize = "12px";
                        inner.style.borderColor = "#d5cec7";
                        inner.className = "rounded";
                        inner.style.display = "inline-block";
                        inner.style.border = '2px solid #d5cec7';
                        if (data.username === "{{username}}") {
                            inner.style.backgroundColor = "#dcf8c7";
                            div.style.textAlign = "right";
                        } else {
                            inner.style.backgroundColor = "#ffffff";
                            div.style.textAlign = "left";
                        }
                        div.appendChild(inner);
                        div.style.width = "100%";
                        document.getElementById('message').appendChild(div);
                    }
                });
            });
        </script>
        <style>
           body{
                font-family: Arial, sans-serif;
           }
           div{
                padding: 2px 12px;
                text-align: center;
            }
        </style>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css">
        <title>Messages on Channel {{ channel_id }}</title>
    </head>
    <body>
        <h1>Welcome to Channel {{ channel_id }}</h1>
        <button id="leave">Leave Channel</button>
        <label for="textbox"></label><input id="textbox" placeholder="Message..." type="text">
        <button id="send">Send</button>
        <hr>
        <div id="message">
        </div>
    </body>
</html>

может кто-нибудь помочь? Сообщение об ошибке:

127.0.0.1 - - [11/Jul/2020 14:22:35] "GET /create?channel_name=Hi HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask_socketio/__init__.py", line 46, in __call__
    start_response)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/engineio/middleware.py", line 74, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/scythia/Desktop/Project2/application.py", line 33, in make_channel
    flash("Channel created!")
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/helpers.py", line 423, in flash
    session["_flashes"] = flashes
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/werkzeug/local.py", line 350, in __setitem__
    self._get_current_object()[key] = value
  File "/Users/scythia/Desktop/Project2/venv/lib/python3.7/site-packages/flask/sessions.py", line 103, in _fail
    "The session is unavailable because no secret "
RuntimeError: The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.

Ответы [ 3 ]

0 голосов
/ 13 июля 2020

Нет необходимости изменять ваш код. В командной строке, после настройки среды (если вы используете) и других вещей, просто напишите это; set SECRET_KEY = ваш секретный ключ Где вместо «вашего секретного ключа» установите некоторую строку в качестве секретного ключа.

0 голосов
/ 13 июля 2020

Убедитесь, что вы установили python-dotenv, вы никогда не получите env var с функцией os.getenv(), если ваш файл .env не загружается автоматически (с python-dotenv)

Перед этим вы можно вручную установить app.secret_key = 'xxx', чтобы убедиться, что это проблема, о которой я упоминал выше.

0 голосов
/ 11 июля 2020

Изменить

Вы пытались изменить app.run(debug=True) на socketio.run(app, debug=True), как указано в Flask -SocketIO docs ?

from flask import Flask, render_template
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

if __name__ == '__main__':
    socketio.run(app)

Не тестировалось.



Исходный ответ

Вот отрывок из Flask docs :

from flask import Flask, session, redirect, url_for, request
from markupsafe import escape

app = Flask(__name__)

# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

Таким образом, вы должны изменить app.config["SECRET_KEY"] = os.getenv("SECRET_KEY") на app.secret_key = os.getenv("SECRET_KEY").

https://flask-socketio.readthedocs.io/en/latest/#initialization

...